mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Use U8Span in IFileSystem instead of string
This commit is contained in:
parent
396c3ef791
commit
c141b72912
@ -152,7 +152,7 @@ Module,DescriptionStart,DescriptionEnd,Name,Summary
|
||||
|
||||
2,6061,,InvalidOffset,
|
||||
2,6062,,InvalidSize,
|
||||
2,6063,,NullArgument,
|
||||
2,6063,,NullptrArgument,
|
||||
2,6065,,InvalidMountName,
|
||||
2,6066,,ExtensionSizeTooLarge,
|
||||
2,6067,,ExtensionSizeInvalid,
|
||||
|
|
@ -62,9 +62,9 @@ namespace LibHac.Common
|
||||
return new U8Span(_buffer.Slice(start, length));
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlySpan<byte>(U8Span value) => value.Value;
|
||||
public static implicit operator ReadOnlySpan<byte>(in U8Span value) => value.Value;
|
||||
|
||||
public static explicit operator string(U8Span value) => value.ToString();
|
||||
public static explicit operator string(in U8Span value) => value.ToString();
|
||||
public static explicit operator U8Span(string value) => new U8Span(value);
|
||||
|
||||
public override string ToString()
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using LibHac.FsSystem;
|
||||
|
||||
namespace LibHac.Fs.Accessors
|
||||
{
|
||||
@ -10,22 +8,10 @@ namespace LibHac.Fs.Accessors
|
||||
|
||||
public FileSystemAccessor Parent { get; }
|
||||
|
||||
private IFileSystem ParentFs { get; }
|
||||
private string Path { get; }
|
||||
|
||||
public DirectoryAccessor(IDirectory baseDirectory, FileSystemAccessor parent, IFileSystem parentFs, string path)
|
||||
public DirectoryAccessor(IDirectory baseDirectory, FileSystemAccessor parent)
|
||||
{
|
||||
Directory = baseDirectory;
|
||||
Parent = parent;
|
||||
ParentFs = parentFs;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public IEnumerable<DirectoryEntryEx> Read()
|
||||
{
|
||||
CheckIfDisposed();
|
||||
|
||||
return ParentFs.EnumerateEntries(Path, "*", SearchOptions.Default);
|
||||
}
|
||||
|
||||
public Result Read(out long entriesRead, Span<DirectoryEntry> entryBuffer)
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Common;
|
||||
|
||||
namespace LibHac.Fs.Accessors
|
||||
{
|
||||
@ -28,44 +28,44 @@ namespace LibHac.Fs.Accessors
|
||||
MountNameGenerator = nameGenerator;
|
||||
}
|
||||
|
||||
public Result CreateDirectory(string path)
|
||||
public Result CreateDirectory(U8Span path)
|
||||
{
|
||||
return FileSystem.CreateDirectory(path);
|
||||
}
|
||||
|
||||
public Result CreateFile(string path, long size, CreateFileOptions options)
|
||||
public Result CreateFile(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
return FileSystem.CreateFile(path, size, options);
|
||||
}
|
||||
|
||||
public Result DeleteDirectory(string path)
|
||||
public Result DeleteDirectory(U8Span path)
|
||||
{
|
||||
return FileSystem.DeleteDirectory(path);
|
||||
}
|
||||
|
||||
public Result DeleteDirectoryRecursively(string path)
|
||||
public Result DeleteDirectoryRecursively(U8Span path)
|
||||
{
|
||||
return FileSystem.DeleteDirectoryRecursively(path);
|
||||
}
|
||||
|
||||
public Result CleanDirectoryRecursively(string path)
|
||||
public Result CleanDirectoryRecursively(U8Span path)
|
||||
{
|
||||
return FileSystem.CleanDirectoryRecursively(path);
|
||||
}
|
||||
|
||||
public Result DeleteFile(string path)
|
||||
public Result DeleteFile(U8Span path)
|
||||
{
|
||||
return FileSystem.DeleteFile(path);
|
||||
}
|
||||
|
||||
public Result OpenDirectory(out DirectoryAccessor directory, string path, OpenDirectoryMode mode)
|
||||
public Result OpenDirectory(out DirectoryAccessor directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
|
||||
Result rc = FileSystem.OpenDirectory(out IDirectory rawDirectory, path, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
var accessor = new DirectoryAccessor(rawDirectory, this, FileSystem, path);
|
||||
var accessor = new DirectoryAccessor(rawDirectory, this);
|
||||
|
||||
lock (_locker)
|
||||
{
|
||||
@ -76,7 +76,7 @@ namespace LibHac.Fs.Accessors
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result OpenFile(out FileAccessor file, string path, OpenMode mode)
|
||||
public Result OpenFile(out FileAccessor file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
|
||||
@ -94,42 +94,32 @@ namespace LibHac.Fs.Accessors
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result RenameDirectory(string oldPath, string newPath)
|
||||
public Result RenameDirectory(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
return FileSystem.RenameDirectory(oldPath, newPath);
|
||||
}
|
||||
|
||||
public Result RenameFile(string oldPath, string newPath)
|
||||
public Result RenameFile(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
return FileSystem.RenameFile(oldPath, newPath);
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
{
|
||||
return FileSystem.DirectoryExists(path);
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
return FileSystem.FileExists(path);
|
||||
}
|
||||
|
||||
public Result GetEntryType(out DirectoryEntryType type, string path)
|
||||
public Result GetEntryType(out DirectoryEntryType type, U8Span path)
|
||||
{
|
||||
return FileSystem.GetEntryType(out type, path);
|
||||
}
|
||||
|
||||
public Result GetFreeSpaceSize(out long freeSpace, string path)
|
||||
public Result GetFreeSpaceSize(out long freeSpace, U8Span path)
|
||||
{
|
||||
return FileSystem.GetFreeSpaceSize(out freeSpace, path);
|
||||
}
|
||||
|
||||
public Result GetTotalSpaceSize(out long totalSpace, string path)
|
||||
public Result GetTotalSpaceSize(out long totalSpace, U8Span path)
|
||||
{
|
||||
return FileSystem.GetTotalSpaceSize(out totalSpace, path);
|
||||
}
|
||||
|
||||
public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
|
||||
public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
return FileSystem.GetFileTimeStampRaw(out timeStamp, path);
|
||||
}
|
||||
@ -144,7 +134,7 @@ namespace LibHac.Fs.Accessors
|
||||
return FileSystem.Commit();
|
||||
}
|
||||
|
||||
public Result QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId)
|
||||
public Result QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, U8Span path, QueryId queryId)
|
||||
{
|
||||
return FileSystem.QueryEntry(outBuffer, inBuffer, queryId, path);
|
||||
}
|
||||
|
@ -1,20 +1,22 @@
|
||||
namespace LibHac.Fs
|
||||
using LibHac.Common;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
public abstract class AttributeFileSystemBase : FileSystemBase, IAttributeFileSystem
|
||||
{
|
||||
protected abstract Result CreateDirectoryImpl(string path, NxFileAttributes archiveAttribute);
|
||||
protected abstract Result GetFileAttributesImpl(string path, out NxFileAttributes attributes);
|
||||
protected abstract Result SetFileAttributesImpl(string path, NxFileAttributes attributes);
|
||||
protected abstract Result GetFileSizeImpl(out long fileSize, string path);
|
||||
protected abstract Result CreateDirectoryImpl(U8Span path, NxFileAttributes archiveAttribute);
|
||||
protected abstract Result GetFileAttributesImpl(out NxFileAttributes attributes, U8Span path);
|
||||
protected abstract Result SetFileAttributesImpl(U8Span path, NxFileAttributes attributes);
|
||||
protected abstract Result GetFileSizeImpl(out long fileSize, U8Span path);
|
||||
|
||||
public Result CreateDirectory(string path, NxFileAttributes archiveAttribute)
|
||||
public Result CreateDirectory(U8Span path, NxFileAttributes archiveAttribute)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return CreateDirectoryImpl(path, archiveAttribute);
|
||||
}
|
||||
|
||||
public Result GetFileAttributes(out NxFileAttributes attributes, string path)
|
||||
public Result GetFileAttributes(out NxFileAttributes attributes, U8Span path)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
@ -22,17 +24,17 @@
|
||||
return ResultFs.PreconditionViolation.Log();
|
||||
}
|
||||
|
||||
return GetFileAttributesImpl(path, out attributes);
|
||||
return GetFileAttributesImpl(out attributes, path);
|
||||
}
|
||||
|
||||
public Result SetFileAttributes(string path, NxFileAttributes attributes)
|
||||
public Result SetFileAttributes(U8Span path, NxFileAttributes attributes)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return SetFileAttributesImpl(path, attributes);
|
||||
}
|
||||
|
||||
public Result GetFileSize(out long fileSize, string path)
|
||||
public Result GetFileSize(out long fileSize, U8Span path)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
|
@ -4,16 +4,16 @@ namespace LibHac.Fs
|
||||
{
|
||||
internal static class CommonMountNames
|
||||
{
|
||||
public static readonly U8String GameCardMountName = new U8String("@Gc");
|
||||
public static readonly U8String SystemContentMountName = new U8String("@SystemContent");
|
||||
public static readonly U8String UserContentMountName = new U8String("@UserContent");
|
||||
public static readonly U8String SdCardContentMountName = new U8String("@SdCardContent");
|
||||
public static readonly U8String CalibrationPartitionMountName = new U8String("@CalibFile");
|
||||
public static readonly U8String SafePartitionMountName = new U8String("@Safe");
|
||||
public static readonly U8String UserPartitionMountName = new U8String("@User");
|
||||
public static readonly U8String SystemPartitionMountName = new U8String("@System");
|
||||
public static readonly U8String SdCardMountName = new U8String("@Sdcard");
|
||||
public static readonly U8String HostMountName = new U8String("@Host");
|
||||
public static readonly U8String GameCardFileSystemMountName = new U8String("@Gc");
|
||||
public static readonly U8String ContentStorageSystemMountName = new U8String("@SystemContent");
|
||||
public static readonly U8String ContentStorageUserMountName = new U8String("@UserContent");
|
||||
public static readonly U8String ContentStorageSdCardMountName = new U8String("@SdCardContent");
|
||||
public static readonly U8String BisCalibrationFilePartitionMountName = new U8String("@CalibFile");
|
||||
public static readonly U8String BisSafeModePartitionMountName = new U8String("@Safe");
|
||||
public static readonly U8String BisUserPartitionMountName = new U8String("@User");
|
||||
public static readonly U8String BisSystemPartitionMountName = new U8String("@System");
|
||||
public static readonly U8String SdCardFileSystemMountName = new U8String("@Sdcard");
|
||||
public static readonly U8String HostRootFileSystemMountName = new U8String("@Host");
|
||||
public static readonly U8String RegisteredUpdatePartitionMountName = new U8String("@RegUpdate");
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace LibHac.Fs
|
||||
|
||||
private Result Initialize(IFileSystem baseFileSystem, U8Span path, OpenMode mode)
|
||||
{
|
||||
Result rc = baseFileSystem.OpenFile(out IFile file, path.ToString(), mode);
|
||||
Result rc = baseFileSystem.OpenFile(out IFile file, path, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
SetFile(file);
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using LibHac.Common;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
@ -9,85 +10,86 @@ namespace LibHac.Fs
|
||||
private int _disposedState;
|
||||
protected bool IsDisposed => _disposedState != 0;
|
||||
|
||||
protected abstract Result CreateDirectoryImpl(string path);
|
||||
protected abstract Result CreateFileImpl(string path, long size, CreateFileOptions options);
|
||||
protected abstract Result DeleteDirectoryImpl(string path);
|
||||
protected abstract Result DeleteDirectoryRecursivelyImpl(string path);
|
||||
protected abstract Result CleanDirectoryRecursivelyImpl(string path);
|
||||
protected abstract Result DeleteFileImpl(string path);
|
||||
protected abstract Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode);
|
||||
protected abstract Result OpenFileImpl(out IFile file, string path, OpenMode mode);
|
||||
protected abstract Result RenameDirectoryImpl(string oldPath, string newPath);
|
||||
protected abstract Result RenameFileImpl(string oldPath, string newPath);
|
||||
protected abstract Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path);
|
||||
protected abstract Result CreateDirectoryImpl(U8Span path);
|
||||
protected abstract Result CreateFileImpl(U8Span path, long size, CreateFileOptions options);
|
||||
protected abstract Result DeleteDirectoryImpl(U8Span path);
|
||||
protected abstract Result DeleteDirectoryRecursivelyImpl(U8Span path);
|
||||
protected abstract Result CleanDirectoryRecursivelyImpl(U8Span path);
|
||||
protected abstract Result DeleteFileImpl(U8Span path);
|
||||
protected abstract Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode);
|
||||
protected abstract Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode);
|
||||
protected abstract Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath);
|
||||
protected abstract Result RenameFileImpl(U8Span oldPath, U8Span newPath);
|
||||
protected abstract Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path);
|
||||
protected abstract Result CommitImpl();
|
||||
|
||||
protected virtual Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected virtual Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
freeSpace = default;
|
||||
return ResultFs.NotImplemented.Log();
|
||||
}
|
||||
|
||||
protected virtual Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected virtual Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
totalSpace = default;
|
||||
return ResultFs.NotImplemented.Log();
|
||||
}
|
||||
|
||||
protected virtual Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
|
||||
protected virtual Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
timeStamp = default;
|
||||
return ResultFs.NotImplemented.Log();
|
||||
}
|
||||
|
||||
protected virtual Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
|
||||
protected virtual Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId,
|
||||
U8Span path)
|
||||
{
|
||||
return ResultFs.NotImplemented.Log();
|
||||
}
|
||||
|
||||
public Result CreateDirectory(string path)
|
||||
public Result CreateDirectory(U8Span path)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return CreateDirectoryImpl(path);
|
||||
}
|
||||
|
||||
public Result CreateFile(string path, long size, CreateFileOptions options)
|
||||
public Result CreateFile(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return CreateFileImpl(path, size, options);
|
||||
}
|
||||
|
||||
public Result DeleteDirectory(string path)
|
||||
public Result DeleteDirectory(U8Span path)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return DeleteDirectoryImpl(path);
|
||||
}
|
||||
|
||||
public Result DeleteDirectoryRecursively(string path)
|
||||
public Result DeleteDirectoryRecursively(U8Span path)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return DeleteDirectoryRecursivelyImpl(path);
|
||||
}
|
||||
|
||||
public Result CleanDirectoryRecursively(string path)
|
||||
public Result CleanDirectoryRecursively(U8Span path)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return CleanDirectoryRecursivelyImpl(path);
|
||||
}
|
||||
|
||||
public Result DeleteFile(string path)
|
||||
public Result DeleteFile(U8Span path)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return DeleteFileImpl(path);
|
||||
}
|
||||
|
||||
public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
public Result OpenDirectory(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
@ -95,10 +97,10 @@ namespace LibHac.Fs
|
||||
return ResultFs.PreconditionViolation.Log();
|
||||
}
|
||||
|
||||
if (path == null)
|
||||
if (path.IsNull())
|
||||
{
|
||||
directory = default;
|
||||
return ResultFs.NullArgument.Log();
|
||||
return ResultFs.NullptrArgument.Log();
|
||||
}
|
||||
|
||||
if ((mode & ~OpenDirectoryMode.All) != 0 || (mode & OpenDirectoryMode.All) == 0)
|
||||
@ -110,7 +112,7 @@ namespace LibHac.Fs
|
||||
return OpenDirectoryImpl(out directory, path, mode);
|
||||
}
|
||||
|
||||
public Result OpenFile(out IFile file, string path, OpenMode mode)
|
||||
public Result OpenFile(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
@ -118,10 +120,10 @@ namespace LibHac.Fs
|
||||
return ResultFs.PreconditionViolation.Log();
|
||||
}
|
||||
|
||||
if (path == null)
|
||||
if (path.IsNull())
|
||||
{
|
||||
file = default;
|
||||
return ResultFs.NullArgument.Log();
|
||||
return ResultFs.NullptrArgument.Log();
|
||||
}
|
||||
|
||||
if ((mode & ~OpenMode.All) != 0 || (mode & OpenMode.ReadWrite) == 0)
|
||||
@ -133,21 +135,21 @@ namespace LibHac.Fs
|
||||
return OpenFileImpl(out file, path, mode);
|
||||
}
|
||||
|
||||
public Result RenameDirectory(string oldPath, string newPath)
|
||||
public Result RenameDirectory(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return RenameDirectoryImpl(oldPath, newPath);
|
||||
}
|
||||
|
||||
public Result RenameFile(string oldPath, string newPath)
|
||||
public Result RenameFile(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return RenameFileImpl(oldPath, newPath);
|
||||
}
|
||||
|
||||
public Result GetEntryType(out DirectoryEntryType entryType, string path)
|
||||
public Result GetEntryType(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
@ -158,7 +160,7 @@ namespace LibHac.Fs
|
||||
return GetEntryTypeImpl(out entryType, path);
|
||||
}
|
||||
|
||||
public Result GetFreeSpaceSize(out long freeSpace, string path)
|
||||
public Result GetFreeSpaceSize(out long freeSpace, U8Span path)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
@ -169,7 +171,7 @@ namespace LibHac.Fs
|
||||
return GetFreeSpaceSizeImpl(out freeSpace, path);
|
||||
}
|
||||
|
||||
public Result GetTotalSpaceSize(out long totalSpace, string path)
|
||||
public Result GetTotalSpaceSize(out long totalSpace, U8Span path)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
@ -180,7 +182,7 @@ namespace LibHac.Fs
|
||||
return GetTotalSpaceSizeImpl(out totalSpace, path);
|
||||
}
|
||||
|
||||
public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
|
||||
public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
@ -198,7 +200,7 @@ namespace LibHac.Fs
|
||||
return CommitImpl();
|
||||
}
|
||||
|
||||
public Result QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
|
||||
public Result QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, U8Span path)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Accessors;
|
||||
|
||||
namespace LibHac.Fs
|
||||
@ -7,20 +8,20 @@ namespace LibHac.Fs
|
||||
{
|
||||
public Result CreateDirectory(string path)
|
||||
{
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.CreateDirectory(subPath.ToString());
|
||||
rc = fileSystem.CreateDirectory(subPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.CreateDirectory(subPath.ToString());
|
||||
rc = fileSystem.CreateDirectory(subPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -33,20 +34,20 @@ namespace LibHac.Fs
|
||||
|
||||
public Result CreateFile(string path, long size, CreateFileOptions options)
|
||||
{
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.CreateFile(subPath.ToString(), size, options);
|
||||
rc = fileSystem.CreateFile(subPath, size, options);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\", size: {size}");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.CreateFile(subPath.ToString(), size, options);
|
||||
rc = fileSystem.CreateFile(subPath, size, options);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -54,20 +55,20 @@ namespace LibHac.Fs
|
||||
|
||||
public Result DeleteDirectory(string path)
|
||||
{
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.DeleteDirectory(subPath.ToString());
|
||||
rc = fileSystem.DeleteDirectory(subPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.DeleteDirectory(subPath.ToString());
|
||||
rc = fileSystem.DeleteDirectory(subPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -75,20 +76,20 @@ namespace LibHac.Fs
|
||||
|
||||
public Result DeleteDirectoryRecursively(string path)
|
||||
{
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.DeleteDirectoryRecursively(subPath.ToString());
|
||||
rc = fileSystem.DeleteDirectoryRecursively(subPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.DeleteDirectoryRecursively(subPath.ToString());
|
||||
rc = fileSystem.DeleteDirectoryRecursively(subPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -96,20 +97,20 @@ namespace LibHac.Fs
|
||||
|
||||
public Result CleanDirectoryRecursively(string path)
|
||||
{
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.CleanDirectoryRecursively(subPath.ToString());
|
||||
rc = fileSystem.CleanDirectoryRecursively(subPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.CleanDirectoryRecursively(subPath.ToString());
|
||||
rc = fileSystem.CleanDirectoryRecursively(subPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -117,20 +118,20 @@ namespace LibHac.Fs
|
||||
|
||||
public Result DeleteFile(string path)
|
||||
{
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.DeleteFile(subPath.ToString());
|
||||
rc = fileSystem.DeleteFile(subPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.DeleteFile(subPath.ToString());
|
||||
rc = fileSystem.DeleteFile(subPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -138,10 +139,10 @@ namespace LibHac.Fs
|
||||
|
||||
public Result RenameDirectory(string oldPath, string newPath)
|
||||
{
|
||||
Result rc = FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan<char> oldSubPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan<char> newSubPath);
|
||||
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (oldFileSystem != newFileSystem)
|
||||
@ -152,14 +153,14 @@ namespace LibHac.Fs
|
||||
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
|
||||
rc = oldFileSystem.RenameDirectory(oldSubPath, newSubPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString());
|
||||
rc = oldFileSystem.RenameDirectory(oldSubPath, newSubPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -167,10 +168,10 @@ namespace LibHac.Fs
|
||||
|
||||
public Result RenameFile(string oldPath, string newPath)
|
||||
{
|
||||
Result rc = FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan<char> oldSubPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan<char> newSubPath);
|
||||
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (oldFileSystem != newFileSystem)
|
||||
@ -181,14 +182,14 @@ namespace LibHac.Fs
|
||||
if (IsEnabledAccessLog() && oldFileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
|
||||
rc = oldFileSystem.RenameFile(oldSubPath, newSubPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString());
|
||||
rc = oldFileSystem.RenameFile(oldSubPath, newSubPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -198,20 +199,20 @@ namespace LibHac.Fs
|
||||
{
|
||||
type = default;
|
||||
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.GetEntryType(out type, subPath.ToString());
|
||||
rc = fileSystem.GetEntryType(out type, subPath);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.GetEntryType(out type, subPath.ToString());
|
||||
rc = fileSystem.GetEntryType(out type, subPath);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -221,13 +222,13 @@ namespace LibHac.Fs
|
||||
{
|
||||
handle = default;
|
||||
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.OpenFile(out FileAccessor file, subPath.ToString(), mode);
|
||||
rc = fileSystem.OpenFile(out FileAccessor file, subPath, mode);
|
||||
handle = new FileHandle(file);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
@ -235,7 +236,7 @@ namespace LibHac.Fs
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.OpenFile(out FileAccessor file, subPath.ToString(), mode);
|
||||
rc = fileSystem.OpenFile(out FileAccessor file, subPath, mode);
|
||||
handle = new FileHandle(file);
|
||||
}
|
||||
|
||||
@ -246,13 +247,13 @@ namespace LibHac.Fs
|
||||
{
|
||||
handle = default;
|
||||
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
|
||||
{
|
||||
TimeSpan startTime = Time.GetCurrent();
|
||||
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath.ToString(), mode);
|
||||
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath, mode);
|
||||
handle = new DirectoryHandle(dir);
|
||||
TimeSpan endTime = Time.GetCurrent();
|
||||
|
||||
@ -260,7 +261,7 @@ namespace LibHac.Fs
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath.ToString(), mode);
|
||||
rc = fileSystem.OpenDirectory(out DirectoryAccessor dir, subPath, mode);
|
||||
handle = new DirectoryHandle(dir);
|
||||
}
|
||||
|
||||
@ -271,30 +272,30 @@ namespace LibHac.Fs
|
||||
{
|
||||
freeSpace = default;
|
||||
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return fileSystem.GetFreeSpaceSize(out freeSpace, subPath.ToString());
|
||||
return fileSystem.GetFreeSpaceSize(out freeSpace, subPath);
|
||||
}
|
||||
|
||||
public Result GetTotalSpaceSize(out long totalSpace, string path)
|
||||
{
|
||||
totalSpace = default;
|
||||
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return fileSystem.GetTotalSpaceSize(out totalSpace, subPath.ToString());
|
||||
return fileSystem.GetTotalSpaceSize(out totalSpace, subPath);
|
||||
}
|
||||
|
||||
public Result GetFileTimeStamp(out FileTimeStampRaw timeStamp, string path)
|
||||
{
|
||||
timeStamp = default;
|
||||
|
||||
Result rc = FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath);
|
||||
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return fileSystem.GetFileTimeStampRaw(out timeStamp, subPath.ToString());
|
||||
return fileSystem.GetFileTimeStampRaw(out timeStamp, subPath);
|
||||
}
|
||||
|
||||
public Result Commit(string mountName)
|
||||
|
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Accessors;
|
||||
using LibHac.FsService;
|
||||
@ -97,24 +99,43 @@ namespace LibHac.Fs
|
||||
rc.ThrowIfFailure();
|
||||
}
|
||||
|
||||
internal Result FindFileSystem(ReadOnlySpan<char> path, out FileSystemAccessor fileSystem, out ReadOnlySpan<char> subPath)
|
||||
internal Result FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, U8Span path)
|
||||
{
|
||||
fileSystem = default;
|
||||
subPath = default;
|
||||
|
||||
Result rc = GetMountName(path, out ReadOnlySpan<char> mountName, out subPath);
|
||||
if (path.IsNull())
|
||||
return ResultFs.NullptrArgument.Log();
|
||||
|
||||
int hostMountNameLen = StringUtils.GetLength(CommonMountNames.HostRootFileSystemMountName);
|
||||
if (StringUtils.Compare(path, CommonMountNames.HostRootFileSystemMountName, hostMountNameLen) == 0)
|
||||
{
|
||||
return ResultFs.NotMounted.Log();
|
||||
}
|
||||
|
||||
Result rc = GetMountNameAndSubPath(out MountName mountName, out subPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = MountTable.Find(mountName.ToString(), out fileSystem);
|
||||
rc = MountTable.Find(StringUtils.Utf8ZToString(mountName.Name), out fileSystem);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
internal static Result GetMountName(ReadOnlySpan<char> path, out ReadOnlySpan<char> mountName, out ReadOnlySpan<char> subPath)
|
||||
internal static Result GetMountNameAndSubPath(out MountName mountName, out U8Span subPath, U8Span path)
|
||||
{
|
||||
int mountLen = 0;
|
||||
int maxMountLen = Math.Min(path.Length, PathTools.MountNameLengthMax);
|
||||
|
||||
if (PathUtility.IsWindowsDrive(path) || PathUtility.IsUnc(path))
|
||||
{
|
||||
StringUtils.Copy(mountName.Name, CommonMountNames.HostRootFileSystemMountName);
|
||||
mountName.Name[PathTools.MountNameLengthMax] = StringTraits.NullTerminator;
|
||||
|
||||
subPath = path;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= maxMountLen; i++)
|
||||
{
|
||||
if (path[i] == PathTools.MountSeparator)
|
||||
@ -124,7 +145,7 @@ namespace LibHac.Fs
|
||||
}
|
||||
}
|
||||
|
||||
if (mountLen == 0)
|
||||
if (mountLen == 0 || mountLen > maxMountLen)
|
||||
{
|
||||
mountName = default;
|
||||
subPath = default;
|
||||
@ -132,18 +153,30 @@ namespace LibHac.Fs
|
||||
return ResultFs.InvalidMountName.Log();
|
||||
}
|
||||
|
||||
mountName = path.Slice(0, mountLen);
|
||||
U8Span subPathTemp = path.Slice(mountLen + 1);
|
||||
|
||||
if (mountLen + 1 < path.Length)
|
||||
{
|
||||
subPath = path.Slice(mountLen + 1);
|
||||
}
|
||||
else
|
||||
if (subPathTemp.Length == 0 || !PathTool.IsAnySeparator(subPathTemp[0]))
|
||||
{
|
||||
mountName = default;
|
||||
subPath = default;
|
||||
|
||||
return ResultFs.InvalidPathFormat.Log();
|
||||
}
|
||||
|
||||
path.Value.Slice(0, mountLen).CopyTo(mountName.Name);
|
||||
mountName.Name[mountLen] = StringTraits.NullTerminator;
|
||||
subPath = subPathTemp;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 16)]
|
||||
[DebuggerDisplay("{ToString()}")]
|
||||
internal struct MountName
|
||||
{
|
||||
public Span<byte> Name => SpanHelpers.AsByteSpan(ref this);
|
||||
|
||||
public override string ToString() => new U8Span(Name).ToString();
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
namespace LibHac.Fs
|
||||
using LibHac.Common;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
public interface IAttributeFileSystem : IFileSystem
|
||||
{
|
||||
Result CreateDirectory(string path, NxFileAttributes archiveAttribute);
|
||||
Result GetFileAttributes(out NxFileAttributes attributes, string path);
|
||||
Result SetFileAttributes(string path, NxFileAttributes attributes);
|
||||
Result GetFileSize(out long fileSize, string path);
|
||||
Result CreateDirectory(U8Span path, NxFileAttributes archiveAttribute);
|
||||
Result GetFileAttributes(out NxFileAttributes attributes, U8Span path);
|
||||
Result SetFileAttributes(U8Span path, NxFileAttributes attributes);
|
||||
Result GetFileSize(out long fileSize, U8Span path);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.FsSystem;
|
||||
|
||||
namespace LibHac.Fs
|
||||
@ -23,7 +24,7 @@ namespace LibHac.Fs
|
||||
/// Specified path already exists as either a file or directory: <see cref="ResultFs.PathAlreadyExists"/>
|
||||
/// Insufficient free space to create the file: <see cref="ResultFs.InsufficientFreeSpace"/>
|
||||
/// </remarks>
|
||||
Result CreateFile(string path, long size, CreateFileOptions options);
|
||||
Result CreateFile(U8Span path, long size, CreateFileOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified file.
|
||||
@ -35,7 +36,7 @@ namespace LibHac.Fs
|
||||
///
|
||||
/// The specified path does not exist or is a directory: <see cref="ResultFs.PathNotFound"/>
|
||||
/// </remarks>
|
||||
Result DeleteFile(string path);
|
||||
Result DeleteFile(U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Creates all directories and subdirectories in the specified path unless they already exist.
|
||||
@ -49,7 +50,7 @@ namespace LibHac.Fs
|
||||
/// Specified path already exists as either a file or directory: <see cref="ResultFs.PathAlreadyExists"/>
|
||||
/// Insufficient free space to create the directory: <see cref="ResultFs.InsufficientFreeSpace"/>
|
||||
/// </remarks>
|
||||
Result CreateDirectory(string path);
|
||||
Result CreateDirectory(U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified directory.
|
||||
@ -62,7 +63,7 @@ namespace LibHac.Fs
|
||||
/// The specified path does not exist or is a file: <see cref="ResultFs.PathNotFound"/>
|
||||
/// The specified directory is not empty: <see cref="ResultFs.DirectoryNotEmpty"/>
|
||||
/// </remarks>
|
||||
Result DeleteDirectory(string path);
|
||||
Result DeleteDirectory(U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified directory and any subdirectories and files in the directory.
|
||||
@ -74,7 +75,7 @@ namespace LibHac.Fs
|
||||
///
|
||||
/// The specified path does not exist or is a file: <see cref="ResultFs.PathNotFound"/>
|
||||
/// </remarks>
|
||||
Result DeleteDirectoryRecursively(string path);
|
||||
Result DeleteDirectoryRecursively(U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes any subdirectories and files in the specified directory.
|
||||
@ -86,7 +87,7 @@ namespace LibHac.Fs
|
||||
///
|
||||
/// The specified path does not exist or is a file: <see cref="ResultFs.PathNotFound"/>
|
||||
/// </remarks>
|
||||
Result CleanDirectoryRecursively(string path);
|
||||
Result CleanDirectoryRecursively(U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Renames or moves a file to a new location.
|
||||
@ -102,7 +103,7 @@ namespace LibHac.Fs
|
||||
/// <paramref name="newPath"/>'s parent directory does not exist: <see cref="ResultFs.PathNotFound"/>
|
||||
/// <paramref name="newPath"/> already exists as either a file or directory: <see cref="ResultFs.PathAlreadyExists"/>
|
||||
/// </remarks>
|
||||
Result RenameFile(string oldPath, string newPath);
|
||||
Result RenameFile(U8Span oldPath, U8Span newPath);
|
||||
|
||||
/// <summary>
|
||||
/// Renames or moves a directory to a new location.
|
||||
@ -119,7 +120,7 @@ namespace LibHac.Fs
|
||||
/// <paramref name="newPath"/> already exists as either a file or directory: <see cref="ResultFs.PathAlreadyExists"/>
|
||||
/// Either <paramref name="oldPath"/> or <paramref name="newPath"/> is a subpath of the other: <see cref="ResultFs.DestinationIsSubPathOfSource"/>
|
||||
/// </remarks>
|
||||
Result RenameDirectory(string oldPath, string newPath);
|
||||
Result RenameDirectory(U8Span oldPath, U8Span newPath);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified path is a file or directory, or does not exist.
|
||||
@ -127,7 +128,7 @@ namespace LibHac.Fs
|
||||
/// <param name="entryType">If the operation returns successfully, the <see cref="DirectoryEntryType"/> of the file.</param>
|
||||
/// <param name="path">The full path to check.</param>
|
||||
/// <returns>The <see cref="Result"/> of the requested operation.</returns>
|
||||
Result GetEntryType(out DirectoryEntryType entryType, string path);
|
||||
Result GetEntryType(out DirectoryEntryType entryType, U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of available free space on a drive, in bytes.
|
||||
@ -135,7 +136,7 @@ namespace LibHac.Fs
|
||||
/// <param name="freeSpace">If the operation returns successfully, the amount of free space available on the drive, in bytes.</param>
|
||||
/// <param name="path">The path of the drive to query. Unused in almost all cases.</param>
|
||||
/// <returns>The <see cref="Result"/> of the requested operation.</returns>
|
||||
Result GetFreeSpaceSize(out long freeSpace, string path);
|
||||
Result GetFreeSpaceSize(out long freeSpace, U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total size of storage space on a drive, in bytes.
|
||||
@ -143,7 +144,7 @@ namespace LibHac.Fs
|
||||
/// <param name="totalSpace">If the operation returns successfully, the total size of the drive, in bytes.</param>
|
||||
/// <param name="path">The path of the drive to query. Unused in almost all cases.</param>
|
||||
/// <returns>The <see cref="Result"/> of the requested operation.</returns>
|
||||
Result GetTotalSpaceSize(out long totalSpace, string path);
|
||||
Result GetTotalSpaceSize(out long totalSpace, U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Opens an <see cref="IFile"/> instance for the specified path.
|
||||
@ -158,7 +159,7 @@ namespace LibHac.Fs
|
||||
///
|
||||
/// The specified path does not exist or is a directory: <see cref="ResultFs.PathNotFound"/>
|
||||
/// </remarks>
|
||||
Result OpenFile(out IFile file, string path, OpenMode mode);
|
||||
Result OpenFile(out IFile file, U8Span path, OpenMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IDirectory"/> instance for enumerating the specified directory.
|
||||
@ -173,7 +174,7 @@ namespace LibHac.Fs
|
||||
///
|
||||
/// The specified path does not exist or is a file: <see cref="ResultFs.PathNotFound"/>
|
||||
/// </remarks>
|
||||
Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode);
|
||||
Result OpenDirectory(out IDirectory directory, U8Span path, OpenDirectoryMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Commits any changes to a transactional file system.
|
||||
@ -194,7 +195,7 @@ namespace LibHac.Fs
|
||||
///
|
||||
/// The specified path does not exist: <see cref="ResultFs.PathNotFound"/>
|
||||
/// </remarks>
|
||||
Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path);
|
||||
Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, U8Span path);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a query on the specified file.
|
||||
@ -208,7 +209,7 @@ namespace LibHac.Fs
|
||||
/// <param name="queryId">The type of query to perform.</param>
|
||||
/// <param name="path">The full path of the file to query.</param>
|
||||
/// <returns>The <see cref="Result"/> of the requested operation.</returns>
|
||||
Result QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path);
|
||||
Result QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, U8Span path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -18,59 +18,55 @@ namespace LibHac.Fs
|
||||
FsTable = new FileTable();
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
return FsTable.AddDirectory(new U8Span(path));
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path, NxFileAttributes archiveAttribute)
|
||||
protected override Result CreateDirectoryImpl(U8Span path, NxFileAttributes archiveAttribute)
|
||||
{
|
||||
var u8Path = new U8Span(path);
|
||||
|
||||
Result rc = FsTable.AddDirectory(u8Path);
|
||||
Result rc = FsTable.AddDirectory(path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = FsTable.GetDirectory(u8Path, out DirectoryNode dir);
|
||||
rc = FsTable.GetDirectory(path, out DirectoryNode dir);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
dir.Attributes = archiveAttribute;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
var u8Path = new U8Span(path);
|
||||
|
||||
Result rc = FsTable.AddFile(u8Path);
|
||||
Result rc = FsTable.AddFile(path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = FsTable.GetFile(u8Path, out FileNode file);
|
||||
rc = FsTable.GetFile(path, out FileNode file);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return file.File.SetSize(size);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
return FsTable.DeleteDirectory(new U8Span(path), false);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
return FsTable.DeleteDirectory(new U8Span(path), true);
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
return FsTable.CleanDirectory(new U8Span(path));
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
return FsTable.DeleteFile(new U8Span(path));
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
|
||||
@ -81,12 +77,11 @@ namespace LibHac.Fs
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
var u8Path = new U8Span(path);
|
||||
|
||||
Result rc = FsTable.GetFile(u8Path, out FileNode fileNode);
|
||||
Result rc = FsTable.GetFile(path, out FileNode fileNode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
file = new MemoryFile(mode, fileNode.File);
|
||||
@ -94,27 +89,25 @@ namespace LibHac.Fs
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
return FsTable.RenameDirectory(new U8Span(oldPath), new U8Span(newPath));
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
return FsTable.RenameFile(new U8Span(oldPath), new U8Span(newPath));
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
var u8Path = new U8Span(path);
|
||||
|
||||
if (FsTable.GetFile(u8Path, out _).IsSuccess())
|
||||
if (FsTable.GetFile(path, out _).IsSuccess())
|
||||
{
|
||||
entryType = DirectoryEntryType.File;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (FsTable.GetDirectory(u8Path, out _).IsSuccess())
|
||||
if (FsTable.GetDirectory(path, out _).IsSuccess())
|
||||
{
|
||||
entryType = DirectoryEntryType.Directory;
|
||||
return Result.Success;
|
||||
@ -129,17 +122,15 @@ namespace LibHac.Fs
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetFileAttributesImpl(string path, out NxFileAttributes attributes)
|
||||
protected override Result GetFileAttributesImpl(out NxFileAttributes attributes, U8Span path)
|
||||
{
|
||||
var u8Path = new U8Span(path);
|
||||
|
||||
if (FsTable.GetFile(u8Path, out FileNode file).IsSuccess())
|
||||
if (FsTable.GetFile(path, out FileNode file).IsSuccess())
|
||||
{
|
||||
attributes = file.Attributes;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (FsTable.GetDirectory(u8Path, out DirectoryNode dir).IsSuccess())
|
||||
if (FsTable.GetDirectory(path, out DirectoryNode dir).IsSuccess())
|
||||
{
|
||||
attributes = dir.Attributes;
|
||||
return Result.Success;
|
||||
@ -149,17 +140,15 @@ namespace LibHac.Fs
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result SetFileAttributesImpl(string path, NxFileAttributes attributes)
|
||||
protected override Result SetFileAttributesImpl(U8Span path, NxFileAttributes attributes)
|
||||
{
|
||||
var u8Path = new U8Span(path);
|
||||
|
||||
if (FsTable.GetFile(u8Path, out FileNode file).IsSuccess())
|
||||
if (FsTable.GetFile(path, out FileNode file).IsSuccess())
|
||||
{
|
||||
file.Attributes = attributes;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (FsTable.GetDirectory(u8Path, out DirectoryNode dir).IsSuccess())
|
||||
if (FsTable.GetDirectory(path, out DirectoryNode dir).IsSuccess())
|
||||
{
|
||||
dir.Attributes = attributes;
|
||||
return Result.Success;
|
||||
@ -168,11 +157,9 @@ namespace LibHac.Fs
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result GetFileSizeImpl(out long fileSize, string path)
|
||||
protected override Result GetFileSizeImpl(out long fileSize, U8Span path)
|
||||
{
|
||||
var u8Path = new U8Span(path);
|
||||
|
||||
if (FsTable.GetFile(u8Path, out FileNode file).IsSuccess())
|
||||
if (FsTable.GetFile(path, out FileNode file).IsSuccess())
|
||||
{
|
||||
return file.File.GetSize(out fileSize);
|
||||
}
|
||||
@ -646,7 +633,12 @@ namespace LibHac.Fs
|
||||
|
||||
while (parser.MoveNext())
|
||||
{
|
||||
if (!TryFindChildDirectory(new U8Span(parser.GetCurrent()), current, out DirectoryNode child))
|
||||
var currentDir = new U8Span(parser.GetCurrent());
|
||||
|
||||
// End if we've hit a trailing separator
|
||||
if (currentDir.IsEmpty() && parser.IsFinished()) break;
|
||||
|
||||
if (!TryFindChildDirectory(currentDir, current, out DirectoryNode child))
|
||||
{
|
||||
directory = default;
|
||||
return ResultFs.PathNotFound.Log();
|
||||
|
@ -6,7 +6,7 @@ namespace LibHac.Fs
|
||||
{
|
||||
public static Result CheckMountName(U8Span name)
|
||||
{
|
||||
if (name.IsNull()) return ResultFs.NullArgument.Log();
|
||||
if (name.IsNull()) return ResultFs.NullptrArgument.Log();
|
||||
|
||||
if (name.Length > 0 && name[0] == '@') return ResultFs.InvalidMountName.Log();
|
||||
if (!CheckMountNameImpl(name)) return ResultFs.InvalidMountName.Log();
|
||||
@ -16,7 +16,7 @@ namespace LibHac.Fs
|
||||
|
||||
public static Result CheckMountNameAcceptingReservedMountName(U8Span name)
|
||||
{
|
||||
if (name.IsNull()) return ResultFs.NullArgument.Log();
|
||||
if (name.IsNull()) return ResultFs.NullptrArgument.Log();
|
||||
|
||||
if (!CheckMountNameImpl(name)) return ResultFs.InvalidMountName.Log();
|
||||
|
||||
|
@ -301,7 +301,7 @@ namespace LibHac.Fs
|
||||
/// <summary>Error code: 2002-6062; Inner value: 0x2f5c02</summary>
|
||||
public static Result.Base InvalidSize => new Result.Base(ModuleFs, 6062);
|
||||
/// <summary>Error code: 2002-6063; Inner value: 0x2f5e02</summary>
|
||||
public static Result.Base NullArgument => new Result.Base(ModuleFs, 6063);
|
||||
public static Result.Base NullptrArgument => new Result.Base(ModuleFs, 6063);
|
||||
/// <summary>Error code: 2002-6065; Inner value: 0x2f6202</summary>
|
||||
public static Result.Base InvalidMountName => new Result.Base(ModuleFs, 6065);
|
||||
/// <summary>Error code: 2002-6066; Inner value: 0x2f6402</summary>
|
||||
|
@ -31,11 +31,11 @@ namespace LibHac.Fs.Shim
|
||||
switch (storageId)
|
||||
{
|
||||
case ContentStorageId.System:
|
||||
return CommonMountNames.SystemContentMountName;
|
||||
return CommonMountNames.ContentStorageSystemMountName;
|
||||
case ContentStorageId.User:
|
||||
return CommonMountNames.UserContentMountName;
|
||||
return CommonMountNames.ContentStorageUserMountName;
|
||||
case ContentStorageId.SdCard:
|
||||
return CommonMountNames.SdCardContentMountName;
|
||||
return CommonMountNames.ContentStorageSdCardMountName;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(storageId), storageId, null);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ namespace LibHac.Fs.Shim
|
||||
{
|
||||
char letter = GetGameCardMountNameSuffix(PartitionId);
|
||||
|
||||
string mountName = $"{CommonMountNames.GameCardMountName}{letter}{Handle.Value:x8}";
|
||||
string mountName = $"{CommonMountNames.GameCardFileSystemMountName}{letter}{Handle.Value:x8}";
|
||||
new U8Span(mountName).Value.CopyTo(nameBuffer);
|
||||
|
||||
return Result.Success;
|
||||
|
@ -23,7 +23,7 @@ namespace LibHac.FsService.Creators
|
||||
fileSystem = default;
|
||||
|
||||
if (!IsValidPartitionId(partitionId)) return ResultFs.InvalidArgument.Log();
|
||||
if (rootPath == null) return ResultFs.NullArgument.Log();
|
||||
if (rootPath == null) return ResultFs.NullptrArgument.Log();
|
||||
|
||||
if (Config.TryGetFileSystem(out fileSystem, partitionId))
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ namespace LibHac.FsService.Creators
|
||||
|
||||
public Result SetFileSystem(IFileSystem fileSystem, BisPartitionId partitionId)
|
||||
{
|
||||
if (fileSystem == null) return ResultFs.NullArgument.Log();
|
||||
if (fileSystem == null) return ResultFs.NullptrArgument.Log();
|
||||
if (!IsValidPartitionId(partitionId)) return ResultFs.InvalidArgument.Log();
|
||||
|
||||
PartitionFileSystems[GetArrayIndex(partitionId)] = fileSystem;
|
||||
@ -24,7 +24,7 @@ namespace LibHac.FsService.Creators
|
||||
|
||||
public Result SetPath(string path, BisPartitionId partitionId)
|
||||
{
|
||||
if (path == null) return ResultFs.NullArgument.Log();
|
||||
if (path == null) return ResultFs.NullptrArgument.Log();
|
||||
if (!IsValidPartitionId(partitionId)) return ResultFs.InvalidArgument.Log();
|
||||
|
||||
PartitionPaths[GetArrayIndex(partitionId)] = path;
|
||||
|
@ -1,9 +1,10 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsService.Creators
|
||||
{
|
||||
public interface ISubDirectoryFileSystemCreator
|
||||
{
|
||||
Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, string path);
|
||||
Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path);
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ namespace LibHac.FsService.Creators
|
||||
fileSystem = default;
|
||||
extraDataAccessor = default;
|
||||
|
||||
string saveDataPath = $"/{saveDataId:x16}";
|
||||
var saveDataPath = $"/{saveDataId:x16}".ToU8String();
|
||||
|
||||
Result rc = sourceFileSystem.GetEntryType(out DirectoryEntryType entryType, saveDataPath);
|
||||
if (rc.IsFailure())
|
||||
@ -40,7 +40,7 @@ namespace LibHac.FsService.Creators
|
||||
case DirectoryEntryType.Directory:
|
||||
if (!allowDirectorySaveData) return ResultFs.InvalidSaveDataEntryType.Log();
|
||||
|
||||
rc = SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem subDirFs, sourceFileSystem, saveDataPath.ToU8String());
|
||||
rc = SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem subDirFs, sourceFileSystem, saveDataPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
bool isPersistentSaveData = type != SaveDataType.Temporary;
|
||||
|
@ -6,7 +6,7 @@ namespace LibHac.FsService.Creators
|
||||
{
|
||||
public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator
|
||||
{
|
||||
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, string path)
|
||||
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path)
|
||||
{
|
||||
subDirFileSystem = default;
|
||||
|
||||
|
@ -1113,7 +1113,7 @@ namespace LibHac.FsService
|
||||
string.Empty, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = saveDirFs.CleanDirectoryRecursively("/");
|
||||
rc = saveDirFs.CleanDirectoryRecursively("/".ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
SaveDataIndexerReader reader = default;
|
||||
|
@ -65,7 +65,7 @@ namespace LibHac.FsService
|
||||
{
|
||||
fileSystem = default;
|
||||
|
||||
string contentDirPath = default;
|
||||
U8String contentDirPath = default;
|
||||
IFileSystem baseFileSystem = default;
|
||||
bool isEncrypted = false;
|
||||
Result rc;
|
||||
@ -74,15 +74,15 @@ namespace LibHac.FsService
|
||||
{
|
||||
case ContentStorageId.System:
|
||||
rc = OpenBisFileSystem(out baseFileSystem, string.Empty, BisPartitionId.System);
|
||||
contentDirPath = $"/{ContentDirectoryName}";
|
||||
contentDirPath = $"/{ContentDirectoryName}".ToU8String();
|
||||
break;
|
||||
case ContentStorageId.User:
|
||||
rc = OpenBisFileSystem(out baseFileSystem, string.Empty, BisPartitionId.User);
|
||||
contentDirPath = $"/{ContentDirectoryName}";
|
||||
contentDirPath = $"/{ContentDirectoryName}".ToU8String();
|
||||
break;
|
||||
case ContentStorageId.SdCard:
|
||||
rc = OpenSdCardFileSystem(out baseFileSystem);
|
||||
contentDirPath = $"/{NintendoDirectoryName}/{ContentDirectoryName}";
|
||||
contentDirPath = $"/{NintendoDirectoryName}/{ContentDirectoryName}".ToU8String();
|
||||
isEncrypted = true;
|
||||
break;
|
||||
default:
|
||||
@ -92,7 +92,7 @@ namespace LibHac.FsService
|
||||
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
baseFileSystem.EnsureDirectoryExists(contentDirPath);
|
||||
baseFileSystem.EnsureDirectoryExists(contentDirPath.ToString());
|
||||
|
||||
rc = FsCreators.SubDirectoryFileSystemCreator.Create(out IFileSystem subDirFileSystem,
|
||||
baseFileSystem, contentDirPath);
|
||||
@ -199,7 +199,7 @@ namespace LibHac.FsService
|
||||
|
||||
string saveDataPath = $"/{saveDataId:x16}";
|
||||
|
||||
rc = fileSystem.GetEntryType(out _, saveDataPath);
|
||||
rc = fileSystem.GetEntryType(out _, saveDataPath.ToU8Span());
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
@ -337,7 +337,7 @@ namespace LibHac.FsService
|
||||
|
||||
string metaFilePath = $"/{(int)type:x8}.meta";
|
||||
|
||||
return metaDirFs.OpenFile(out file, metaFilePath, OpenMode.ReadWrite);
|
||||
return metaDirFs.OpenFile(out file, metaFilePath.ToU8Span(), OpenMode.ReadWrite);
|
||||
}
|
||||
|
||||
public Result DeleteSaveDataMetaFiles(ulong saveDataId, SaveDataSpaceId spaceId)
|
||||
@ -348,7 +348,7 @@ namespace LibHac.FsService
|
||||
{
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = metaDirFs.DeleteDirectoryRecursively($"/{saveDataId:x16}");
|
||||
rc = metaDirFs.DeleteDirectoryRecursively($"/{saveDataId:x16}".ToU8Span());
|
||||
|
||||
if (rc.IsFailure() && !ResultFs.PathNotFound.Includes(rc))
|
||||
return rc;
|
||||
@ -369,7 +369,7 @@ namespace LibHac.FsService
|
||||
|
||||
if (size < 0) return ResultFs.OutOfRange.Log();
|
||||
|
||||
return metaDirFs.CreateFile(metaFilePath, size, CreateFileOptions.None);
|
||||
return metaDirFs.CreateFile(metaFilePath.ToU8Span(), size, CreateFileOptions.None);
|
||||
}
|
||||
|
||||
public Result CreateSaveDataFileSystem(ulong saveDataId, ref SaveDataAttribute attribute,
|
||||
@ -391,7 +391,7 @@ namespace LibHac.FsService
|
||||
{
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
string saveDataPath = GetSaveDataIdPath(saveDataId);
|
||||
var saveDataPath = GetSaveDataIdPath(saveDataId).ToU8Span();
|
||||
|
||||
rc = fileSystem.GetEntryType(out DirectoryEntryType entryType, saveDataPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
@ -13,9 +13,9 @@ namespace LibHac.FsService
|
||||
|
||||
if (!createPathIfMissing)
|
||||
{
|
||||
if (path == null) return ResultFs.NullArgument.Log();
|
||||
if (path == null) return ResultFs.NullptrArgument.Log();
|
||||
|
||||
Result rc = baseFileSystem.GetEntryType(out DirectoryEntryType entryType, path);
|
||||
Result rc = baseFileSystem.GetEntryType(out DirectoryEntryType entryType, path.ToU8Span());
|
||||
|
||||
if (rc.IsFailure() || entryType != DirectoryEntryType.Directory)
|
||||
{
|
||||
@ -32,9 +32,9 @@ namespace LibHac.FsService
|
||||
{
|
||||
subFileSystem = default;
|
||||
|
||||
if (path == null) return ResultFs.NullArgument.Log();
|
||||
if (path == null) return ResultFs.NullptrArgument.Log();
|
||||
|
||||
Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);
|
||||
Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path.ToU8Span(), OpenDirectoryMode.Directory);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem fs, baseFileSystem, path.ToU8String());
|
||||
|
@ -6,13 +6,13 @@ namespace LibHac.FsSystem
|
||||
{
|
||||
public class AesXtsDirectory : IDirectory
|
||||
{
|
||||
private string Path { get; }
|
||||
private U8String Path { get; }
|
||||
private OpenDirectoryMode Mode { get; }
|
||||
|
||||
private IFileSystem BaseFileSystem { get; }
|
||||
private IDirectory BaseDirectory { get; }
|
||||
|
||||
public AesXtsDirectory(IFileSystem baseFs, IDirectory baseDir, string path, OpenDirectoryMode mode)
|
||||
public AesXtsDirectory(IFileSystem baseFs, IDirectory baseDir, U8String path, OpenDirectoryMode mode)
|
||||
{
|
||||
BaseFileSystem = baseFs;
|
||||
BaseDirectory = baseDir;
|
||||
@ -38,7 +38,7 @@ namespace LibHac.FsSystem
|
||||
else
|
||||
{
|
||||
string entryName = Util.GetUtf8StringNullTerminated(entry.Name);
|
||||
entry.Size = GetAesXtsFileSize(PathTools.Combine(Path, entryName));
|
||||
entry.Size = GetAesXtsFileSize(PathTools.Combine(Path.ToString(), entryName).ToU8Span());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -56,7 +56,7 @@ namespace LibHac.FsSystem
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
private long GetAesXtsFileSize(string path)
|
||||
private long GetAesXtsFileSize(U8Span path)
|
||||
{
|
||||
const long magicOffset = 0x20;
|
||||
const long fileSizeOffset = 0x48;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
@ -6,7 +7,7 @@ namespace LibHac.FsSystem
|
||||
public class AesXtsFile : FileBase
|
||||
{
|
||||
private IFile BaseFile { get; }
|
||||
private string Path { get; }
|
||||
private U8String Path { get; }
|
||||
private byte[] KekSeed { get; }
|
||||
private byte[] VerificationKey { get; }
|
||||
private int BlockSize { get; }
|
||||
@ -17,7 +18,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
internal const int HeaderLength = 0x4000;
|
||||
|
||||
public AesXtsFile(OpenMode mode, IFile baseFile, string path, ReadOnlySpan<byte> kekSeed, ReadOnlySpan<byte> verificationKey, int blockSize)
|
||||
public AesXtsFile(OpenMode mode, IFile baseFile, U8String path, ReadOnlySpan<byte> kekSeed, ReadOnlySpan<byte> verificationKey, int blockSize)
|
||||
{
|
||||
Mode = mode;
|
||||
BaseFile = baseFile;
|
||||
@ -30,7 +31,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
baseFile.GetSize(out long fileSize).ThrowIfFailure();
|
||||
|
||||
if (!Header.TryDecryptHeader(Path, KekSeed, VerificationKey))
|
||||
if (!Header.TryDecryptHeader(Path.ToString(), KekSeed, VerificationKey))
|
||||
{
|
||||
ThrowHelper.ThrowResult(ResultFs.AesXtsFileHeaderInvalidKeys.Value, "NAX0 key derivation failed.");
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
@ -28,12 +29,12 @@ namespace LibHac.FsSystem
|
||||
BlockSize = blockSize;
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
return BaseFileSystem.CreateDirectory(path);
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
return CreateFile(path, size, options, new byte[0x20]);
|
||||
}
|
||||
@ -46,14 +47,14 @@ namespace LibHac.FsSystem
|
||||
/// <param name="options">Flags to control how the file is created.
|
||||
/// Should usually be <see cref="CreateFileOptions.None"/></param>
|
||||
/// <param name="key">The 256-bit key containing a 128-bit data key followed by a 128-bit tweak key.</param>
|
||||
public Result CreateFile(string path, long size, CreateFileOptions options, byte[] key)
|
||||
public Result CreateFile(U8Span path, long size, CreateFileOptions options, byte[] key)
|
||||
{
|
||||
long containerSize = AesXtsFile.HeaderLength + Util.AlignUp(size, 0x10);
|
||||
|
||||
Result rc = BaseFileSystem.CreateFile(path, containerSize, options);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
var header = new AesXtsFileHeader(key, size, path, KekSource, ValidationKey);
|
||||
var header = new AesXtsFileHeader(key, size, path.ToString(), KekSource, ValidationKey);
|
||||
|
||||
rc = BaseFileSystem.OpenFile(out IFile baseFile, path, OpenMode.Write);
|
||||
if (rc.IsFailure()) return rc;
|
||||
@ -67,57 +68,52 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
return BaseFileSystem.DeleteDirectory(path);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
return BaseFileSystem.DeleteDirectoryRecursively(path);
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
return BaseFileSystem.CleanDirectoryRecursively(path);
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
return BaseFileSystem.DeleteFile(path);
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
Result rc = BaseFileSystem.OpenDirectory(out IDirectory baseDir, path, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
directory = new AesXtsDirectory(BaseFileSystem, baseDir, path, mode);
|
||||
directory = new AesXtsDirectory(BaseFileSystem, baseDir, path.ToU8String(), mode);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
Result rc = BaseFileSystem.OpenFile(out IFile baseFile, path, mode | OpenMode.Read);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
var xtsFile = new AesXtsFile(mode, baseFile, path, KekSource, ValidationKey, BlockSize);
|
||||
var xtsFile = new AesXtsFile(mode, baseFile, path.ToU8String(), KekSource, ValidationKey, BlockSize);
|
||||
|
||||
file = xtsFile;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
oldPath = PathTools.Normalize(oldPath);
|
||||
newPath = PathTools.Normalize(newPath);
|
||||
|
||||
// todo: Return proper result codes
|
||||
|
||||
// Official code procedure:
|
||||
@ -133,11 +129,11 @@ namespace LibHac.FsSystem
|
||||
|
||||
try
|
||||
{
|
||||
RenameDirectoryImpl(oldPath, newPath, false);
|
||||
RenameDirectoryImpl(oldPath.ToString(), newPath.ToString(), false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
RenameDirectoryImpl(oldPath, newPath, true);
|
||||
RenameDirectoryImpl(oldPath.ToString(), newPath.ToString(), true);
|
||||
BaseFileSystem.RenameDirectory(oldPath, newPath);
|
||||
|
||||
throw;
|
||||
@ -176,26 +172,23 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
oldPath = PathTools.Normalize(oldPath);
|
||||
newPath = PathTools.Normalize(newPath);
|
||||
|
||||
// todo: Return proper result codes
|
||||
|
||||
AesXtsFileHeader header = ReadXtsHeader(oldPath, oldPath);
|
||||
AesXtsFileHeader header = ReadXtsHeader(oldPath.ToString(), oldPath.ToString());
|
||||
|
||||
Result rc = BaseFileSystem.RenameFile(oldPath, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
try
|
||||
{
|
||||
WriteXtsHeader(header, newPath, newPath);
|
||||
WriteXtsHeader(header, newPath.ToString(), newPath.ToString());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
BaseFileSystem.RenameFile(newPath, oldPath);
|
||||
WriteXtsHeader(header, oldPath, oldPath);
|
||||
WriteXtsHeader(header, oldPath.ToString(), oldPath.ToString());
|
||||
|
||||
throw;
|
||||
}
|
||||
@ -203,22 +196,22 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
return BaseFileSystem.GetEntryType(out entryType, path);
|
||||
}
|
||||
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
return BaseFileSystem.GetFileTimeStampRaw(out timeStamp, path);
|
||||
}
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
return BaseFileSystem.GetFreeSpaceSize(out freeSpace, path);
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
return BaseFileSystem.GetTotalSpaceSize(out totalSpace, path);
|
||||
}
|
||||
@ -228,7 +221,8 @@ namespace LibHac.FsSystem
|
||||
return BaseFileSystem.Commit();
|
||||
}
|
||||
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId,
|
||||
U8Span path)
|
||||
{
|
||||
return BaseFileSystem.QueryEntry(outBuffer, inBuffer, queryId, path);
|
||||
}
|
||||
@ -250,7 +244,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
header = null;
|
||||
|
||||
Result rc = BaseFileSystem.OpenFile(out IFile file, filePath, OpenMode.Read);
|
||||
Result rc = BaseFileSystem.OpenFile(out IFile file, filePath.ToU8Span(), OpenMode.Read);
|
||||
if (rc.IsFailure()) return false;
|
||||
|
||||
using (file)
|
||||
@ -268,7 +262,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
header.EncryptHeader(keyPath, KekSource, ValidationKey);
|
||||
|
||||
BaseFileSystem.OpenFile(out IFile file, filePath, OpenMode.ReadWrite);
|
||||
BaseFileSystem.OpenFile(out IFile file, filePath.ToU8Span(), OpenMode.ReadWrite);
|
||||
|
||||
using (file)
|
||||
{
|
||||
|
@ -7,20 +7,35 @@ namespace LibHac.FsSystem
|
||||
{
|
||||
public class ConcatenationDirectory : IDirectory
|
||||
{
|
||||
private string Path { get; }
|
||||
private OpenDirectoryMode Mode { get; }
|
||||
|
||||
private ConcatenationFileSystem ParentFileSystem { get; }
|
||||
private IFileSystem BaseFileSystem { get; }
|
||||
private IDirectory ParentDirectory { get; }
|
||||
private IFileSystem BaseFileSystem { get; }
|
||||
private ConcatenationFileSystem ParentFileSystem { get; }
|
||||
|
||||
public ConcatenationDirectory(ConcatenationFileSystem fs, IFileSystem baseFs, IDirectory parentDirectory, OpenDirectoryMode mode, string path)
|
||||
private FsPath _path;
|
||||
|
||||
public ConcatenationDirectory(ConcatenationFileSystem fs, IFileSystem baseFs, IDirectory parentDirectory, OpenDirectoryMode mode, U8Span path)
|
||||
{
|
||||
ParentFileSystem = fs;
|
||||
BaseFileSystem = baseFs;
|
||||
ParentDirectory = parentDirectory;
|
||||
Mode = mode;
|
||||
Path = path;
|
||||
|
||||
StringUtils.Copy(_path.Str, path);
|
||||
_path.Str[PathTools.MaxPathLength] = StringTraits.NullTerminator;
|
||||
|
||||
// Ensure the path ends with a separator
|
||||
int pathLength = StringUtils.GetLength(path, PathTools.MaxPathLength + 1);
|
||||
|
||||
if (pathLength != 0 && _path.Str[pathLength - 1] == StringTraits.DirectorySeparator)
|
||||
return;
|
||||
|
||||
if (pathLength >= PathTools.MaxPathLength)
|
||||
throw new HorizonResultException(ResultFs.TooLongPath.Value, "abort");
|
||||
|
||||
_path.Str[pathLength] = StringTraits.DirectorySeparator;
|
||||
_path.Str[pathLength + 1] = StringTraits.NullTerminator;
|
||||
_path.Str[PathTools.MaxPathLength] = StringTraits.NullTerminator;
|
||||
}
|
||||
|
||||
public Result Read(out long entriesRead, Span<DirectoryEntry> entryBuffer)
|
||||
@ -48,9 +63,12 @@ namespace LibHac.FsSystem
|
||||
if (!Mode.HasFlag(OpenDirectoryMode.NoFileSize))
|
||||
{
|
||||
string entryName = Util.GetUtf8StringNullTerminated(entry.Name);
|
||||
string entryFullPath = PathTools.Combine(Path, entryName);
|
||||
string entryFullPath = PathTools.Combine(_path.ToString(), entryName);
|
||||
|
||||
entry.Size = ParentFileSystem.GetConcatenationFileSize(entryFullPath);
|
||||
rc = ParentFileSystem.GetConcatenationFileSize(out long fileSize, entryFullPath.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
entry.Size = fileSize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +86,7 @@ namespace LibHac.FsSystem
|
||||
entryCount = 0;
|
||||
long count = 0;
|
||||
|
||||
Result rc = BaseFileSystem.OpenDirectory(out IDirectory _, Path,
|
||||
Result rc = BaseFileSystem.OpenDirectory(out IDirectory _, _path,
|
||||
OpenDirectoryMode.All | OpenDirectoryMode.NoFileSize);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
@ -104,7 +122,7 @@ namespace LibHac.FsSystem
|
||||
else
|
||||
{
|
||||
string name = Util.GetUtf8StringNullTerminated(entry.Name);
|
||||
string fullPath = PathTools.Combine(Path, name);
|
||||
var fullPath = PathTools.Combine(_path.ToString(), name).ToU8Span();
|
||||
|
||||
return ParentFileSystem.IsConcatenationFile(fullPath);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
@ -9,15 +10,15 @@ namespace LibHac.FsSystem
|
||||
public class ConcatenationFile : FileBase
|
||||
{
|
||||
private IFileSystem BaseFileSystem { get; }
|
||||
private string FilePath { get; }
|
||||
private U8String FilePath { get; }
|
||||
private List<IFile> Sources { get; }
|
||||
private long SubFileSize { get; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
internal ConcatenationFile(IFileSystem baseFileSystem, string path, IEnumerable<IFile> sources, long subFileSize, OpenMode mode)
|
||||
internal ConcatenationFile(IFileSystem baseFileSystem, U8Span path, IEnumerable<IFile> sources, long subFileSize, OpenMode mode)
|
||||
{
|
||||
BaseFileSystem = baseFileSystem;
|
||||
FilePath = path;
|
||||
FilePath = path.ToU8String();
|
||||
Sources = sources.ToList();
|
||||
SubFileSize = subFileSize;
|
||||
Mode = mode;
|
||||
@ -78,7 +79,8 @@ namespace LibHac.FsSystem
|
||||
long outPos = offset;
|
||||
int remaining = source.Length;
|
||||
|
||||
GetSize(out long fileSize).ThrowIfFailure();
|
||||
rc = GetSize(out long fileSize);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
while (remaining > 0)
|
||||
{
|
||||
@ -151,7 +153,12 @@ namespace LibHac.FsSystem
|
||||
|
||||
for (int i = currentSubFileCount; i < newSubFileCount; i++)
|
||||
{
|
||||
string newSubFilePath = ConcatenationFileSystem.GetSubFilePath(FilePath, i);
|
||||
FsPath newSubFilePath;
|
||||
unsafe { _ = &newSubFilePath; } // workaround for CS0165
|
||||
|
||||
rc = ConcatenationFileSystem.GetSubFilePath(newSubFilePath.Str, FilePath, i);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
newSubFileSize = QuerySubFileSize(i, size, SubFileSize);
|
||||
|
||||
rc = BaseFileSystem.CreateFile(newSubFilePath, newSubFileSize, CreateFileOptions.None);
|
||||
@ -170,7 +177,11 @@ namespace LibHac.FsSystem
|
||||
Sources[i].Dispose();
|
||||
Sources.RemoveAt(i);
|
||||
|
||||
string subFilePath = ConcatenationFileSystem.GetSubFilePath(FilePath, i);
|
||||
FsPath subFilePath;
|
||||
unsafe { _ = &subFilePath; } // workaround for CS0165
|
||||
|
||||
rc = ConcatenationFileSystem.GetSubFilePath(subFilePath.Str, FilePath, i);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = BaseFileSystem.DeleteFile(subFilePath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Buffers.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
@ -47,7 +50,7 @@ namespace LibHac.FsSystem
|
||||
// .NET Core on platforms other than Windows doesn't support getting the
|
||||
// archive flag in FAT file systems. Try to work around that for now for reading,
|
||||
// but writing still won't work properly on those platforms
|
||||
internal bool IsConcatenationFile(string path)
|
||||
internal bool IsConcatenationFile(U8Span path)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
@ -62,14 +65,14 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsConcatenationFileHeuristic(string path)
|
||||
private bool IsConcatenationFileHeuristic(U8Span path)
|
||||
{
|
||||
// Check if the path is a directory
|
||||
Result getTypeResult = BaseFileSystem.GetEntryType(out DirectoryEntryType pathType, path);
|
||||
if (getTypeResult.IsFailure() || pathType != DirectoryEntryType.Directory) return false;
|
||||
|
||||
// Check if the directory contains at least one subfile
|
||||
getTypeResult = BaseFileSystem.GetEntryType(out DirectoryEntryType subFileType, PathTools.Combine(path, "00"));
|
||||
getTypeResult = BaseFileSystem.GetEntryType(out DirectoryEntryType subFileType, PathTools.Combine(path.ToString(), "00").ToU8Span());
|
||||
if (getTypeResult.IsFailure() || subFileType != DirectoryEntryType.File) return false;
|
||||
|
||||
// Make sure the directory contains no subdirectories
|
||||
@ -88,15 +91,14 @@ namespace LibHac.FsSystem
|
||||
return (attributes & NxFileAttributes.Directory) != 0 && (attributes & NxFileAttributes.Archive) != 0;
|
||||
}
|
||||
|
||||
private Result SetConcatenationFileAttribute(string path)
|
||||
private Result SetConcatenationFileAttribute(U8Span path)
|
||||
{
|
||||
return BaseFileSystem.SetFileAttributes(path, NxFileAttributes.Archive);
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
string parent = PathTools.GetParentDirectory(path);
|
||||
var parent = new U8Span(PathTools.GetParentDirectory(path));
|
||||
|
||||
if (IsConcatenationFile(parent))
|
||||
{
|
||||
@ -107,10 +109,8 @@ namespace LibHac.FsSystem
|
||||
return BaseFileSystem.CreateDirectory(path);
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
CreateFileOptions newOptions = options & ~CreateFileOptions.CreateConcatenationFile;
|
||||
|
||||
if (!options.HasFlag(CreateFileOptions.CreateConcatenationFile))
|
||||
@ -119,9 +119,9 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
|
||||
// A concatenation file directory can't contain normal files
|
||||
string parentDir = PathTools.GetParentDirectory(path);
|
||||
ReadOnlySpan<byte> parentDir = PathTools.GetParentDirectory(path);
|
||||
|
||||
if (IsConcatenationFile(parentDir))
|
||||
if (IsConcatenationFile(new U8Span(parentDir)))
|
||||
{
|
||||
// Cannot create a file inside of a concatenation file
|
||||
return ResultFs.PathNotFound.Log();
|
||||
@ -135,7 +135,12 @@ namespace LibHac.FsSystem
|
||||
for (int i = 0; remaining > 0; i++)
|
||||
{
|
||||
long fileSize = Math.Min(SubFileSize, remaining);
|
||||
string fileName = GetSubFilePath(path, i);
|
||||
|
||||
FsPath fileName;
|
||||
unsafe { _ = &fileName; } // workaround for CS0165
|
||||
|
||||
rc = GetSubFilePath(fileName.Str, path, i);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result createSubFileResult = BaseFileSystem.CreateFile(fileName, fileSize, CreateFileOptions.None);
|
||||
|
||||
@ -151,10 +156,8 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (IsConcatenationFile(path))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
@ -163,48 +166,48 @@ namespace LibHac.FsSystem
|
||||
return BaseFileSystem.DeleteDirectory(path);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (IsConcatenationFile(path)) return ResultFs.PathNotFound.Log();
|
||||
|
||||
return BaseFileSystem.DeleteDirectoryRecursively(path);
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (IsConcatenationFile(path)) return ResultFs.PathNotFound.Log();
|
||||
|
||||
return BaseFileSystem.CleanDirectoryRecursively(path);
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (!IsConcatenationFile(path))
|
||||
{
|
||||
return BaseFileSystem.DeleteFile(path);
|
||||
}
|
||||
|
||||
int count = GetSubFileCount(path);
|
||||
Result rc = GetSubFileCount(out int count, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Result rc = BaseFileSystem.DeleteFile(GetSubFilePath(path, i));
|
||||
FsPath subFilePath;
|
||||
unsafe { _ = &subFilePath; } // workaround for CS0165
|
||||
|
||||
rc = GetSubFilePath(subFilePath.Str, path, i);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = BaseFileSystem.DeleteFile(subFilePath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
return BaseFileSystem.DeleteDirectory(path);
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (IsConcatenationFile(path))
|
||||
{
|
||||
@ -218,25 +221,29 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (!IsConcatenationFile(path))
|
||||
{
|
||||
return BaseFileSystem.OpenFile(out file, path, mode);
|
||||
}
|
||||
|
||||
int fileCount = GetSubFileCount(path);
|
||||
Result rc = GetSubFileCount(out int fileCount, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
var files = new List<IFile>();
|
||||
var files = new List<IFile>(fileCount);
|
||||
|
||||
for (int i = 0; i < fileCount; i++)
|
||||
{
|
||||
string filePath = GetSubFilePath(path, i);
|
||||
FsPath subFilePath;
|
||||
unsafe { _ = &subFilePath; } // workaround for CS0165
|
||||
|
||||
Result rc = BaseFileSystem.OpenFile(out IFile subFile, filePath, mode);
|
||||
rc = GetSubFilePath(subFilePath.Str, path, i);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = BaseFileSystem.OpenFile(out IFile subFile, subFilePath, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
files.Add(subFile);
|
||||
@ -246,11 +253,8 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
oldPath = PathTools.Normalize(oldPath);
|
||||
newPath = PathTools.Normalize(newPath);
|
||||
|
||||
if (IsConcatenationFile(oldPath))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
@ -259,11 +263,8 @@ namespace LibHac.FsSystem
|
||||
return BaseFileSystem.RenameDirectory(oldPath, newPath);
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
oldPath = PathTools.Normalize(oldPath);
|
||||
newPath = PathTools.Normalize(newPath);
|
||||
|
||||
if (IsConcatenationFile(oldPath))
|
||||
{
|
||||
return BaseFileSystem.RenameDirectory(oldPath, newPath);
|
||||
@ -274,10 +275,8 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (IsConcatenationFile(path))
|
||||
{
|
||||
entryType = DirectoryEntryType.File;
|
||||
@ -287,17 +286,17 @@ namespace LibHac.FsSystem
|
||||
return BaseFileSystem.GetEntryType(out entryType, path);
|
||||
}
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
return BaseFileSystem.GetFreeSpaceSize(out freeSpace, path);
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
return BaseFileSystem.GetTotalSpaceSize(out totalSpace, path);
|
||||
}
|
||||
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
return BaseFileSystem.GetFileTimeStampRaw(out timeStamp, path);
|
||||
}
|
||||
@ -307,42 +306,101 @@ namespace LibHac.FsSystem
|
||||
return BaseFileSystem.Commit();
|
||||
}
|
||||
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId,
|
||||
U8Span path)
|
||||
{
|
||||
if (queryId != QueryId.MakeConcatFile) return ResultFs.UnsupportedOperationInConcatFsQueryEntry.Log();
|
||||
|
||||
return SetConcatenationFileAttribute(path);
|
||||
}
|
||||
|
||||
private int GetSubFileCount(string dirPath)
|
||||
private Result GetSubFileCount(out int fileCount, U8Span dirPath)
|
||||
{
|
||||
int count = 0;
|
||||
fileCount = default;
|
||||
|
||||
while (BaseFileSystem.FileExists(GetSubFilePath(dirPath, count)))
|
||||
FsPath buffer;
|
||||
unsafe { _ = &buffer; } // workaround for CS0165
|
||||
|
||||
int pathLen = StringUtils.Copy(buffer.Str, dirPath);
|
||||
|
||||
// Make sure we have at least 3 bytes for the sub file name
|
||||
if (pathLen + 3 > PathTools.MaxPathLength)
|
||||
return ResultFs.TooLongPath.Log();
|
||||
|
||||
buffer.Str[pathLen] = StringTraits.DirectorySeparator;
|
||||
Span<byte> subFileName = buffer.Str.Slice(pathLen + 1);
|
||||
|
||||
Result rc;
|
||||
int count;
|
||||
|
||||
for (count = 0; ; count++)
|
||||
{
|
||||
count++;
|
||||
Utf8Formatter.TryFormat(count, subFileName, out _, new StandardFormat('D', 2));
|
||||
|
||||
rc = BaseFileSystem.GetEntryType(out _, buffer);
|
||||
if (rc.IsFailure()) break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
internal static string GetSubFilePath(string dirPath, int index)
|
||||
{
|
||||
return $"{dirPath}/{index:D2}";
|
||||
}
|
||||
|
||||
internal long GetConcatenationFileSize(string path)
|
||||
{
|
||||
int fileCount = GetSubFileCount(path);
|
||||
long size = 0;
|
||||
|
||||
for (int i = 0; i < fileCount; i++)
|
||||
if (!ResultFs.PathNotFound.Includes(rc))
|
||||
{
|
||||
BaseFileSystem.GetFileSize(out long fileSize, GetSubFilePath(path, i)).ThrowIfFailure();
|
||||
size += fileSize;
|
||||
return rc;
|
||||
}
|
||||
|
||||
return size;
|
||||
fileCount = count;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
internal static Result GetSubFilePath(Span<byte> subFilePathBuffer, ReadOnlySpan<byte> basePath, int index)
|
||||
{
|
||||
int basePathLen = StringUtils.Copy(subFilePathBuffer, basePath);
|
||||
|
||||
// Make sure we have at least 3 bytes for the sub file name
|
||||
if (basePathLen + 3 > PathTools.MaxPathLength)
|
||||
return ResultFs.TooLongPath.Log();
|
||||
|
||||
subFilePathBuffer[basePathLen] = StringTraits.DirectorySeparator;
|
||||
|
||||
Utf8Formatter.TryFormat(index, subFilePathBuffer.Slice(basePathLen + 1), out _, new StandardFormat('D', 2));
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
internal Result GetConcatenationFileSize(out long size, ReadOnlySpan<byte> path)
|
||||
{
|
||||
size = default;
|
||||
|
||||
FsPath buffer;
|
||||
unsafe { _ = &buffer; } // workaround for CS0165
|
||||
|
||||
int pathLen = StringUtils.Copy(buffer.Str, path);
|
||||
|
||||
// Make sure we have at least 3 bytes for the sub file name
|
||||
if (pathLen + 3 > PathTools.MaxPathLength)
|
||||
return ResultFs.TooLongPath.Log();
|
||||
|
||||
buffer.Str[pathLen] = StringTraits.DirectorySeparator;
|
||||
Span<byte> subFileName = buffer.Str.Slice(pathLen + 1);
|
||||
|
||||
Result rc;
|
||||
long totalSize = 0;
|
||||
|
||||
for (int i = 0; ; i++)
|
||||
{
|
||||
Utf8Formatter.TryFormat(i, subFileName, out _, new StandardFormat('D', 2));
|
||||
|
||||
rc = BaseFileSystem.GetFileSize(out long fileSize, buffer);
|
||||
if (rc.IsFailure()) break;
|
||||
|
||||
totalSize += fileSize;
|
||||
}
|
||||
|
||||
if (!ResultFs.PathNotFound.Includes(rc))
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
size = totalSize;
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,18 @@
|
||||
using LibHac.Fs;
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
public class DirectorySaveDataFileSystem : FileSystemBase
|
||||
{
|
||||
private const string CommittedDir = "/0/";
|
||||
private const string WorkingDir = "/1/";
|
||||
private const string SyncDir = "/_/";
|
||||
private ReadOnlySpan<byte> CommittedDirectoryBytes => new[] { (byte)'/', (byte)'0', (byte)'/' };
|
||||
private ReadOnlySpan<byte> WorkingDirectoryBytes => new[] { (byte)'/', (byte)'1', (byte)'/' };
|
||||
private ReadOnlySpan<byte> SynchronizingDirectoryBytes => new[] { (byte)'/', (byte)'_', (byte)'/' };
|
||||
|
||||
private U8Span CommittedDirectoryPath => new U8Span(CommittedDirectoryBytes);
|
||||
private U8Span WorkingDirectoryPath => new U8Span(WorkingDirectoryBytes);
|
||||
private U8Span SynchronizingDirectoryPath => new U8Span(SynchronizingDirectoryBytes);
|
||||
|
||||
private IFileSystem BaseFs { get; }
|
||||
private object Locker { get; } = new object();
|
||||
@ -44,18 +50,18 @@ namespace LibHac.FsSystem
|
||||
IsUserSaveData = isUserSaveData;
|
||||
|
||||
// Ensure the working directory exists
|
||||
Result rc = BaseFs.GetEntryType(out _, WorkingDir);
|
||||
Result rc = BaseFs.GetEntryType(out _, WorkingDirectoryPath);
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
if (!ResultFs.PathNotFound.Includes(rc)) return rc;
|
||||
|
||||
rc = BaseFs.CreateDirectory(WorkingDir);
|
||||
rc = BaseFs.CreateDirectory(WorkingDirectoryPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!IsPersistentSaveData) return Result.Success;
|
||||
|
||||
rc = BaseFs.CreateDirectory(CommittedDir);
|
||||
rc = BaseFs.CreateDirectory(CommittedDirectoryPath);
|
||||
|
||||
// Nintendo returns on all failures, but we'll keep going if committed already exists
|
||||
// to avoid confusing people manually creating savedata in emulators
|
||||
@ -65,11 +71,11 @@ namespace LibHac.FsSystem
|
||||
// Only the working directory is needed for temporary savedata
|
||||
if (!IsPersistentSaveData) return Result.Success;
|
||||
|
||||
rc = BaseFs.GetEntryType(out _, CommittedDir);
|
||||
rc = BaseFs.GetEntryType(out _, CommittedDirectoryPath);
|
||||
|
||||
if (rc.IsSuccess())
|
||||
{
|
||||
return SynchronizeDirectory(WorkingDir, CommittedDir);
|
||||
return SynchronizeDirectory(WorkingDirectoryPath, CommittedDirectoryPath);
|
||||
}
|
||||
|
||||
if (!ResultFs.PathNotFound.Includes(rc)) return rc;
|
||||
@ -77,15 +83,19 @@ namespace LibHac.FsSystem
|
||||
// If a previous commit failed, the committed dir may be missing.
|
||||
// Finish that commit by copying the working dir to the committed dir
|
||||
|
||||
rc = SynchronizeDirectory(SyncDir, WorkingDir);
|
||||
rc = SynchronizeDirectory(SynchronizingDirectoryPath, WorkingDirectoryPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFs.RenameDirectory(SyncDir, CommittedDir);
|
||||
return BaseFs.RenameDirectory(SynchronizingDirectoryPath, CommittedDirectoryPath);
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -93,9 +103,13 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -103,9 +117,13 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -113,9 +131,13 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -123,9 +145,13 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -133,9 +159,13 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -143,9 +173,17 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
directory = default;
|
||||
return rc;
|
||||
}
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -153,14 +191,19 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
Result rc = BaseFs.OpenFile(out IFile baseFile, fullPath, mode);
|
||||
rc = BaseFs.OpenFile(out IFile baseFile, fullPath, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
file = new DirectorySaveDataFile(this, baseFile, mode);
|
||||
@ -174,31 +217,55 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
string fullOldPath = GetFullPath(PathTools.Normalize(oldPath));
|
||||
string fullNewPath = GetFullPath(PathTools.Normalize(newPath));
|
||||
FsPath fullCurrentPath;
|
||||
FsPath fullNewPath;
|
||||
unsafe { _ = &fullCurrentPath; } // workaround for CS0165
|
||||
unsafe { _ = &fullNewPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullCurrentPath.Str, oldPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = ResolveFullPath(fullNewPath.Str, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
return BaseFs.RenameDirectory(fullOldPath, fullNewPath);
|
||||
return BaseFs.RenameDirectory(fullCurrentPath, fullNewPath);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
string fullOldPath = GetFullPath(PathTools.Normalize(oldPath));
|
||||
string fullNewPath = GetFullPath(PathTools.Normalize(newPath));
|
||||
FsPath fullCurrentPath;
|
||||
FsPath fullNewPath;
|
||||
unsafe { _ = &fullCurrentPath; } // workaround for CS0165
|
||||
unsafe { _ = &fullNewPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullCurrentPath.Str, oldPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = ResolveFullPath(fullNewPath.Str, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
return BaseFs.RenameFile(fullOldPath, fullNewPath);
|
||||
return BaseFs.RenameFile(fullCurrentPath, fullNewPath);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
string fullPath = GetFullPath(PathTools.Normalize(path));
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
entryType = default;
|
||||
return rc;
|
||||
}
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@ -219,25 +286,31 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
|
||||
// Get rid of the previous commit by renaming the folder
|
||||
Result rc = BaseFs.RenameDirectory(CommittedDir, SyncDir);
|
||||
Result rc = BaseFs.RenameDirectory(CommittedDirectoryPath, SynchronizingDirectoryPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
// If something goes wrong beyond this point, the commit will be
|
||||
// completed the next time the savedata is opened
|
||||
|
||||
rc = SynchronizeDirectory(SyncDir, WorkingDir);
|
||||
rc = SynchronizeDirectory(SynchronizingDirectoryPath, WorkingDirectoryPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFs.RenameDirectory(SyncDir, CommittedDir);
|
||||
return BaseFs.RenameDirectory(SynchronizingDirectoryPath, CommittedDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFullPath(string path)
|
||||
private Result ResolveFullPath(Span<byte> outPath, U8Span relativePath)
|
||||
{
|
||||
return PathTools.Normalize(PathTools.Combine(WorkingDir, path));
|
||||
if (StringUtils.GetLength(relativePath, PathTools.MaxPathLength + 1) > PathTools.MaxPathLength)
|
||||
return ResultFs.TooLongPath.Log();
|
||||
|
||||
StringUtils.Copy(outPath, WorkingDirectoryBytes);
|
||||
outPath[^1] = StringTraits.NullTerminator;
|
||||
|
||||
return PathTool.Normalize(outPath.Slice(2), out _, relativePath, false, false);
|
||||
}
|
||||
|
||||
private Result SynchronizeDirectory(string dest, string src)
|
||||
private Result SynchronizeDirectory(U8Span dest, U8Span src)
|
||||
{
|
||||
Result rc = BaseFs.DeleteDirectoryRecursively(dest);
|
||||
if (rc.IsFailure() && !ResultFs.PathNotFound.Includes(rc)) return rc;
|
||||
@ -245,7 +318,7 @@ namespace LibHac.FsSystem
|
||||
rc = BaseFs.CreateDirectory(dest);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFs.CopyDirectory(BaseFs, src, dest);
|
||||
return BaseFs.CopyDirectory(BaseFs, src.ToString(), dest.ToString());
|
||||
}
|
||||
|
||||
internal void NotifyCloseWritableFile()
|
||||
|
@ -11,9 +11,7 @@ namespace LibHac.FsSystem
|
||||
public static Result IterateDirectoryRecursivelyInternal(IFileSystem fs, Span<byte> workPath,
|
||||
ref DirectoryEntry entry, Blah onEnterDir, Blah onExitDir, Blah onFile)
|
||||
{
|
||||
string currentPath = Util.GetUtf8StringNullTerminated(workPath);
|
||||
|
||||
Result rc = fs.OpenDirectory(out IDirectory _, currentPath, OpenDirectoryMode.All);
|
||||
Result rc = fs.OpenDirectory(out IDirectory _, new U8Span(workPath), OpenDirectoryMode.All);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
onFile(workPath, ref entry);
|
||||
@ -40,7 +38,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
try
|
||||
{
|
||||
Result rc = sourceFs.OpenFile(out srcFile, StringUtils.Utf8ZToString(sourcePath), OpenMode.Read);
|
||||
Result rc = sourceFs.OpenFile(out srcFile, new U8Span(sourcePath), OpenMode.Read);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
FsPath dstPath = default;
|
||||
@ -52,12 +50,10 @@ namespace LibHac.FsSystem
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
string dstPathStr = StringUtils.Utf8ZToString(dstPath.Str);
|
||||
|
||||
rc = destFs.CreateFile(dstPathStr, dirEntry.Size, CreateFileOptions.None);
|
||||
rc = destFs.CreateFile(dstPath, dirEntry.Size, CreateFileOptions.None);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = destFs.OpenFile(out dstFile, dstPathStr, OpenMode.Write);
|
||||
rc = destFs.OpenFile(out dstFile, dstPath, OpenMode.Write);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
long fileSize = dirEntry.Size;
|
||||
|
@ -31,12 +31,12 @@ namespace LibHac.FsSystem
|
||||
{
|
||||
destFs.CreateOrOverwriteFile(subDstPath, entry.Size, options);
|
||||
|
||||
rc = sourceFs.OpenFile(out IFile srcFile, subSrcPath, OpenMode.Read);
|
||||
rc = sourceFs.OpenFile(out IFile srcFile, subSrcPath.ToU8Span(), OpenMode.Read);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (srcFile)
|
||||
{
|
||||
rc = destFs.OpenFile(out IFile dstFile, subDstPath, OpenMode.Write | OpenMode.AllowAppend);
|
||||
rc = destFs.OpenFile(out IFile dstFile, subDstPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (dstFile)
|
||||
@ -80,7 +80,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
IFileSystem fs = fileSystem;
|
||||
|
||||
fileSystem.OpenDirectory(out IDirectory directory, path, OpenDirectoryMode.All).ThrowIfFailure();
|
||||
fileSystem.OpenDirectory(out IDirectory directory, path.ToU8Span(), OpenDirectoryMode.All).ThrowIfFailure();
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -199,7 +199,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
public static void SetConcatenationFileAttribute(this IFileSystem fs, string path)
|
||||
{
|
||||
fs.QueryEntry(Span<byte>.Empty, Span<byte>.Empty, QueryId.MakeConcatFile, path);
|
||||
fs.QueryEntry(Span<byte>.Empty, Span<byte>.Empty, QueryId.MakeConcatFile, path.ToU8Span());
|
||||
}
|
||||
|
||||
public static void CleanDirectoryRecursivelyGeneric(IFileSystem fileSystem, string path)
|
||||
@ -213,11 +213,11 @@ namespace LibHac.FsSystem
|
||||
if (entry.Type == DirectoryEntryType.Directory)
|
||||
{
|
||||
CleanDirectoryRecursivelyGeneric(fileSystem, subPath);
|
||||
fs.DeleteDirectory(subPath);
|
||||
fs.DeleteDirectory(subPath.ToU8Span());
|
||||
}
|
||||
else if (entry.Type == DirectoryEntryType.File)
|
||||
{
|
||||
fs.DeleteFile(subPath);
|
||||
fs.DeleteFile(subPath.ToU8Span());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,14 +234,14 @@ namespace LibHac.FsSystem
|
||||
|
||||
public static bool DirectoryExists(this IFileSystem fs, string path)
|
||||
{
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, path.ToU8Span());
|
||||
|
||||
return (rc.IsSuccess() && type == DirectoryEntryType.Directory);
|
||||
}
|
||||
|
||||
public static bool FileExists(this IFileSystem fs, string path)
|
||||
{
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, path);
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, path.ToU8Span());
|
||||
|
||||
return (rc.IsSuccess() && type == DirectoryEntryType.File);
|
||||
}
|
||||
@ -277,12 +277,12 @@ namespace LibHac.FsSystem
|
||||
{
|
||||
string subPath = path.Substring(0, i);
|
||||
|
||||
Result rc = fs.CreateDirectory(subPath);
|
||||
Result rc = fs.CreateDirectory(subPath.ToU8Span());
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return fs.CreateDirectory(path);
|
||||
return fs.CreateDirectory(path.ToU8Span());
|
||||
}
|
||||
|
||||
public static void CreateOrOverwriteFile(this IFileSystem fs, string path, long size)
|
||||
@ -294,9 +294,9 @@ namespace LibHac.FsSystem
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (fs.FileExists(path)) fs.DeleteFile(path);
|
||||
if (fs.FileExists(path)) fs.DeleteFile(path.ToU8Span());
|
||||
|
||||
fs.CreateFile(path, size, CreateFileOptions.None);
|
||||
fs.CreateFile(path.ToU8Span(), size, CreateFileOptions.None);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
@ -30,7 +31,9 @@ namespace LibHac.FsSystem
|
||||
return builder.Overflowed ? ResultFs.TooLongPath.Log() : Result.Success;
|
||||
}
|
||||
|
||||
public static implicit operator U8Span(FsPath value) => new U8Span(value.Str);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static implicit operator U8Span(in FsPath value) => new U8Span(SpanHelpers.AsReadOnlyByteSpan(ref Unsafe.AsRef(in value)));
|
||||
|
||||
public override string ToString() => StringUtils.Utf8ZToString(Str);
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +35,9 @@ namespace LibHac.FsSystem
|
||||
Sources.AddRange(sourceFileSystems);
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
// Open directories from all layers so they can be merged
|
||||
// Only allocate the list for multiple sources if needed
|
||||
@ -107,10 +106,9 @@ namespace LibHac.FsSystem
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
foreach (IFileSystem fs in Sources)
|
||||
{
|
||||
@ -137,10 +135,8 @@ namespace LibHac.FsSystem
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
foreach (IFileSystem fs in Sources)
|
||||
{
|
||||
Result getEntryResult = fs.GetEntryType(out DirectoryEntryType type, path);
|
||||
@ -156,10 +152,8 @@ namespace LibHac.FsSystem
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
foreach (IFileSystem fs in Sources)
|
||||
{
|
||||
Result getEntryResult = fs.GetEntryType(out _, path);
|
||||
@ -174,10 +168,9 @@ namespace LibHac.FsSystem
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId,
|
||||
U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
foreach (IFileSystem fs in Sources)
|
||||
{
|
||||
Result getEntryResult = fs.GetEntryType(out _, path);
|
||||
@ -196,31 +189,31 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result DeleteDirectoryImpl(string path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result DeleteFileImpl(string path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result CreateDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result DeleteDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result DeleteFileImpl(U8Span path) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperation.Log();
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperation.Log();
|
||||
|
||||
private class MergedDirectory : IDirectory
|
||||
{
|
||||
// Needed to open new directories for GetEntryCount
|
||||
private List<IFileSystem> SourceFileSystems { get; }
|
||||
private List<IDirectory> SourceDirs { get; }
|
||||
private string Path { get; }
|
||||
private U8String Path { get; }
|
||||
private OpenDirectoryMode Mode { get; }
|
||||
|
||||
// todo: Efficient way to remove duplicates
|
||||
private HashSet<string> Names { get; } = new HashSet<string>();
|
||||
|
||||
public MergedDirectory(List<IFileSystem> sourceFileSystems, string path, OpenDirectoryMode mode)
|
||||
public MergedDirectory(List<IFileSystem> sourceFileSystems, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
SourceFileSystems = sourceFileSystems;
|
||||
SourceDirs = new List<IDirectory>(sourceFileSystems.Count);
|
||||
Path = path;
|
||||
Path = path.ToU8String();
|
||||
Mode = mode;
|
||||
}
|
||||
|
||||
@ -280,7 +273,7 @@ namespace LibHac.FsSystem
|
||||
long entriesRead;
|
||||
do
|
||||
{
|
||||
dir.Read(out entriesRead, SpanHelpers.AsSpan(ref entry));
|
||||
rc = dir.Read(out entriesRead, SpanHelpers.AsSpan(ref entry));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (entriesRead == 1 && names.Add(StringUtils.Utf8ZToString(entry.Name)))
|
||||
|
@ -30,18 +30,49 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
internal string ResolveLocalPath(string path)
|
||||
private Result ResolveFullPath(out string fullPath, U8Span path)
|
||||
{
|
||||
return PathTools.Combine(BasePath, path);
|
||||
fullPath = default;
|
||||
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
fullPath = PathTools.Combine(BasePath, normalizedPath.ToString());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetFileAttributesImpl(string path, out NxFileAttributes attributes)
|
||||
private Result CheckSubPath(U8Span path1, U8Span path2)
|
||||
{
|
||||
FsPath normalizedPath1;
|
||||
FsPath normalizedPath2;
|
||||
unsafe { _ = &normalizedPath1; } // workaround for CS0165
|
||||
unsafe { _ = &normalizedPath2; } // workaround for CS0165
|
||||
|
||||
Result rc = PathTool.Normalize(normalizedPath1.Str, out _, path1, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = PathTool.Normalize(normalizedPath2.Str, out _, path2, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (PathTool.IsSubpath(normalizedPath1, normalizedPath2))
|
||||
{
|
||||
return ResultFs.DestinationIsSubPathOfSource.Log();
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetFileAttributesImpl(out NxFileAttributes attributes, U8Span path)
|
||||
{
|
||||
attributes = default;
|
||||
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetFileInfo(out FileInfo info, localPath);
|
||||
rc = GetFileInfo(out FileInfo info, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (info.Attributes == (FileAttributes)(-1))
|
||||
@ -54,11 +85,12 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result SetFileAttributesImpl(string path, NxFileAttributes attributes)
|
||||
protected override Result SetFileAttributesImpl(U8Span path, NxFileAttributes attributes)
|
||||
{
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetFileInfo(out FileInfo info, localPath);
|
||||
rc = GetFileInfo(out FileInfo info, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (info.Attributes == (FileAttributes)(-1))
|
||||
@ -81,27 +113,30 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetFileSizeImpl(out long fileSize, string path)
|
||||
protected override Result GetFileSizeImpl(out long fileSize, U8Span path)
|
||||
{
|
||||
fileSize = default;
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
|
||||
Result rc = GetFileInfo(out FileInfo info, localPath);
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = GetFileInfo(out FileInfo info, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return GetSizeInternal(out fileSize, info);
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
return CreateDirectory(path, NxFileAttributes.None);
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path, NxFileAttributes archiveAttribute)
|
||||
protected override Result CreateDirectoryImpl(U8Span path, NxFileAttributes archiveAttribute)
|
||||
{
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetDirInfo(out DirectoryInfo dir, localPath);
|
||||
rc = GetDirInfo(out DirectoryInfo dir, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (dir.Exists)
|
||||
@ -117,11 +152,12 @@ namespace LibHac.FsSystem
|
||||
return CreateDirInternal(dir, archiveAttribute);
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetFileInfo(out FileInfo file, localPath);
|
||||
rc = GetFileInfo(out FileInfo file, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (file.Exists)
|
||||
@ -144,42 +180,45 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetDirInfo(out DirectoryInfo dir, localPath);
|
||||
rc = GetDirInfo(out DirectoryInfo dir, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return DeleteDirectoryInternal(dir, false);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetDirInfo(out DirectoryInfo dir, localPath);
|
||||
rc = GetDirInfo(out DirectoryInfo dir, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return DeleteDirectoryInternal(dir, true);
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
foreach (string file in Directory.EnumerateFiles(localPath))
|
||||
foreach (string file in Directory.EnumerateFiles(fullPath))
|
||||
{
|
||||
Result rc = GetFileInfo(out FileInfo fileInfo, file);
|
||||
rc = GetFileInfo(out FileInfo fileInfo, file);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = DeleteFileInternal(fileInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
foreach (string dir in Directory.EnumerateDirectories(localPath))
|
||||
foreach (string dir in Directory.EnumerateDirectories(fullPath))
|
||||
{
|
||||
Result rc = GetDirInfo(out DirectoryInfo dirInfo, dir);
|
||||
rc = GetDirInfo(out DirectoryInfo dirInfo, dir);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = DeleteDirectoryInternal(dirInfo, true);
|
||||
@ -189,22 +228,24 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetFileInfo(out FileInfo file, localPath);
|
||||
rc = GetFileInfo(out FileInfo file, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return DeleteFileInternal(file);
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = GetDirInfo(out DirectoryInfo dirInfo, localPath);
|
||||
rc = GetDirInfo(out DirectoryInfo dirInfo, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!dirInfo.Attributes.HasFlag(FileAttributes.Directory))
|
||||
@ -225,12 +266,14 @@ namespace LibHac.FsSystem
|
||||
}
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
|
||||
Result rc = GetEntryType(out DirectoryEntryType entryType, path);
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = GetEntryType(out DirectoryEntryType entryType, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (entryType == DirectoryEntryType.Directory)
|
||||
@ -238,59 +281,64 @@ namespace LibHac.FsSystem
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
rc = OpenFileInternal(out FileStream fileStream, localPath, mode);
|
||||
rc = OpenFileInternal(out FileStream fileStream, fullPath, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
file = new LocalFile(fileStream, mode);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
oldPath = PathTools.Normalize(oldPath);
|
||||
newPath = PathTools.Normalize(newPath);
|
||||
Result rc = CheckSubPath(oldPath, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = ResolveFullPath(out string fullCurrentPath, oldPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = ResolveFullPath(out string fullNewPath, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
// Official FS behavior is to do nothing in this case
|
||||
if (oldPath == newPath) return Result.Success;
|
||||
if (fullCurrentPath == fullNewPath) return Result.Success;
|
||||
|
||||
// FS does the subpath check before verifying the path exists
|
||||
if (PathTools.IsSubPath(oldPath.AsSpan(), newPath.AsSpan()))
|
||||
{
|
||||
ThrowHelper.ThrowResult(ResultFs.DestinationIsSubPathOfSource.Value);
|
||||
}
|
||||
|
||||
Result rc = GetDirInfo(out DirectoryInfo srcDir, ResolveLocalPath(oldPath));
|
||||
rc = GetDirInfo(out DirectoryInfo currentDirInfo, fullCurrentPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = GetDirInfo(out DirectoryInfo dstDir, ResolveLocalPath(newPath));
|
||||
rc = GetDirInfo(out DirectoryInfo newDirInfo, fullNewPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return RenameDirInternal(srcDir, dstDir);
|
||||
return RenameDirInternal(currentDirInfo, newDirInfo);
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
string srcLocalPath = ResolveLocalPath(PathTools.Normalize(oldPath));
|
||||
string dstLocalPath = ResolveLocalPath(PathTools.Normalize(newPath));
|
||||
Result rc = ResolveFullPath(out string fullCurrentPath, oldPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = ResolveFullPath(out string fullNewPath, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
// Official FS behavior is to do nothing in this case
|
||||
if (srcLocalPath == dstLocalPath) return Result.Success;
|
||||
if (fullCurrentPath == fullNewPath) return Result.Success;
|
||||
|
||||
Result rc = GetFileInfo(out FileInfo srcFile, srcLocalPath);
|
||||
rc = GetFileInfo(out FileInfo currentFileInfo, fullCurrentPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = GetFileInfo(out FileInfo dstFile, dstLocalPath);
|
||||
rc = GetFileInfo(out FileInfo newFileInfo, fullNewPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return RenameFileInternal(srcFile, dstFile);
|
||||
return RenameFileInternal(currentFileInfo, newFileInfo);
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
entryType = default;
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
|
||||
Result rc = GetDirInfo(out DirectoryInfo dir, localPath);
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = GetDirInfo(out DirectoryInfo dir, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (dir.Exists)
|
||||
@ -299,7 +347,7 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
rc = GetFileInfo(out FileInfo file, localPath);
|
||||
rc = GetFileInfo(out FileInfo file, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (file.Exists)
|
||||
@ -312,30 +360,32 @@ namespace LibHac.FsSystem
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
timeStamp = default;
|
||||
string localPath = ResolveLocalPath(PathTools.Normalize(path));
|
||||
|
||||
Result rc = GetFileInfo(out FileInfo file, localPath);
|
||||
Result rc = ResolveFullPath(out string fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = GetFileInfo(out FileInfo file, fullPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!file.Exists) return ResultFs.PathNotFound.Log();
|
||||
|
||||
timeStamp.Created = new DateTimeOffset(File.GetCreationTime(localPath)).ToUnixTimeSeconds();
|
||||
timeStamp.Accessed = new DateTimeOffset(File.GetLastAccessTime(localPath)).ToUnixTimeSeconds();
|
||||
timeStamp.Modified = new DateTimeOffset(File.GetLastWriteTime(localPath)).ToUnixTimeSeconds();
|
||||
timeStamp.Created = new DateTimeOffset(file.CreationTimeUtc).ToUnixTimeSeconds();
|
||||
timeStamp.Accessed = new DateTimeOffset(file.LastAccessTimeUtc).ToUnixTimeSeconds();
|
||||
timeStamp.Modified = new DateTimeOffset(file.LastWriteTime).ToUnixTimeSeconds();
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
freeSpace = new DriveInfo(BasePath).AvailableFreeSpace;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
totalSpace = new DriveInfo(BasePath).TotalSize;
|
||||
return Result.Success;
|
||||
@ -346,7 +396,8 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId,
|
||||
U8Span path)
|
||||
{
|
||||
return ResultFs.UnsupportedOperation.Log();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibHac.Common;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
@ -31,17 +32,17 @@ namespace LibHac.FsSystem
|
||||
BaseStorage = storage;
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = new PartitionDirectory(this, path, mode);
|
||||
directory = new PartitionDirectory(this, path.ToString(), mode);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
path = PathTools.Normalize(path).TrimStart('/');
|
||||
path = PathTools.Normalize(path.ToString()).TrimStart('/').ToU8Span();
|
||||
|
||||
if (!FileDict.TryGetValue(path, out PartitionFileEntry entry))
|
||||
if (!FileDict.TryGetValue(path.ToString(), out PartitionFileEntry entry))
|
||||
{
|
||||
ThrowHelper.ThrowResult(ResultFs.PathNotFound.Value);
|
||||
}
|
||||
@ -55,18 +56,17 @@ namespace LibHac.FsSystem
|
||||
return new PartitionFile(BaseStorage, HeaderSize + entry.Offset, entry.Size, mode);
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
entryType = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (path == "/")
|
||||
if (path.ToString() == "/")
|
||||
{
|
||||
entryType = DirectoryEntryType.Directory;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (FileDict.ContainsKey(path.TrimStart('/')))
|
||||
if (FileDict.ContainsKey(path.ToString().TrimStart('/')))
|
||||
{
|
||||
entryType = DirectoryEntryType.File;
|
||||
return Result.Success;
|
||||
@ -75,14 +75,14 @@ namespace LibHac.FsSystem
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteFileImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CreateDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteFileImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
|
||||
protected override Result CommitImpl()
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibHac.Common;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
@ -26,7 +27,7 @@ namespace LibHac.FsSystem
|
||||
foreach (DirectoryEntryEx entry in input.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File)
|
||||
.OrderBy(x => x.FullPath, StringComparer.Ordinal))
|
||||
{
|
||||
input.OpenFile(out IFile file, entry.FullPath, OpenMode.Read).ThrowIfFailure();
|
||||
input.OpenFile(out IFile file, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
AddFile(entry.FullPath.TrimStart('/'), file);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
|
||||
@ -40,7 +40,7 @@ namespace LibHac.FsSystem
|
||||
|
||||
ReadOnlySpan<byte> rootPath = new[] { (byte)'/' };
|
||||
|
||||
if (StringUtils.Compare(rootPath, path.ToU8Span(), 2) != 0)
|
||||
if (StringUtils.Compare(rootPath, path, 2) != 0)
|
||||
return ResultFs.PathNotFound.Log();
|
||||
|
||||
directory = new PartitionDirectory(this, mode);
|
||||
@ -48,7 +48,7 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
|
||||
@ -58,7 +58,7 @@ namespace LibHac.FsSystem
|
||||
if (!mode.HasFlag(OpenMode.Read) && !mode.HasFlag(OpenMode.Write))
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
|
||||
int entryIndex = MetaData.FindEntry(path.ToU8Span().Slice(1));
|
||||
int entryIndex = MetaData.FindEntry(path.Slice(1));
|
||||
if (entryIndex < 0) return ResultFs.PathNotFound.Log();
|
||||
|
||||
ref T entry = ref MetaData.GetEntry(entryIndex);
|
||||
@ -68,25 +68,25 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
entryType = default;
|
||||
|
||||
if (!IsInitialized)
|
||||
return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
if (string.IsNullOrEmpty(path) || path[0] != '/')
|
||||
if (path.IsEmpty() || path[0] != '/')
|
||||
return ResultFs.InvalidPathFormat.Log();
|
||||
|
||||
ReadOnlySpan<byte> rootPath = new[] { (byte)'/' };
|
||||
|
||||
if (StringUtils.Compare(rootPath, path.ToU8Span(), 2) == 0)
|
||||
if (StringUtils.Compare(rootPath, path, 2) == 0)
|
||||
{
|
||||
entryType = DirectoryEntryType.Directory;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (MetaData.FindEntry(path.ToU8Span().Slice(1)) >= 0)
|
||||
if (MetaData.FindEntry(path.Slice(1)) >= 0)
|
||||
{
|
||||
entryType = DirectoryEntryType.File;
|
||||
return Result.Success;
|
||||
@ -100,14 +100,14 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteFileImpl(string path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CreateDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result DeleteFileImpl(U8Span path) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyPartitionFileSystem.Log();
|
||||
|
||||
private class PartitionFile : FileBase
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
@ -11,12 +12,12 @@ namespace LibHac.FsSystem
|
||||
BaseFs = baseFileSystem;
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
return BaseFs.OpenDirectory(out directory, path, mode);
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
|
||||
@ -27,12 +28,12 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
return BaseFs.GetEntryType(out entryType, path);
|
||||
}
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
freeSpace = 0;
|
||||
return Result.Success;
|
||||
@ -41,7 +42,7 @@ namespace LibHac.FsSystem
|
||||
// return ResultFs.UnsupportedOperationReadOnlyFileSystemGetSpace.Log();
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
return BaseFs.GetTotalSpaceSize(out totalSpace, path);
|
||||
|
||||
@ -49,7 +50,7 @@ namespace LibHac.FsSystem
|
||||
// return ResultFs.UnsupportedOperationReadOnlyFileSystemGetSpace.Log();
|
||||
}
|
||||
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
return BaseFs.GetFileTimeStampRaw(out timeStamp, path);
|
||||
|
||||
@ -62,20 +63,20 @@ namespace LibHac.FsSystem
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result CreateDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result DeleteDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DeleteFileImpl(string path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result DeleteFileImpl(U8Span path) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyReadOnlyFileSystem.Log();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.RomFs
|
||||
@ -36,7 +37,7 @@ namespace LibHac.FsSystem.RomFs
|
||||
foreach (DirectoryEntryEx entry in input.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File)
|
||||
.OrderBy(x => x.FullPath, StringComparer.Ordinal))
|
||||
{
|
||||
input.OpenFile(out IFile file, entry.FullPath, OpenMode.Read).ThrowIfFailure();
|
||||
input.OpenFile(out IFile file, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
AddFile(entry.FullPath, file);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.RomFs
|
||||
{
|
||||
@ -22,18 +23,17 @@ namespace LibHac.FsSystem.RomFs
|
||||
FileTable = new HierarchicalRomFileTable<RomFileInfo>(dirHashTable, dirEntryTable, fileHashTable, fileEntryTable);
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
entryType = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (FileTable.TryOpenFile(path, out RomFileInfo _))
|
||||
if (FileTable.TryOpenFile(path.ToString(), out RomFileInfo _))
|
||||
{
|
||||
entryType = DirectoryEntryType.File;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (FileTable.TryOpenDirectory(path, out FindPosition _))
|
||||
if (FileTable.TryOpenDirectory(path.ToString(), out FindPosition _))
|
||||
{
|
||||
entryType = DirectoryEntryType.Directory;
|
||||
return Result.Success;
|
||||
@ -47,12 +47,11 @@ namespace LibHac.FsSystem.RomFs
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (!FileTable.TryOpenDirectory(path, out FindPosition position))
|
||||
if (!FileTable.TryOpenDirectory(path.ToString(), out FindPosition position))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
@ -61,12 +60,11 @@ namespace LibHac.FsSystem.RomFs
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (!FileTable.TryOpenFile(path, out RomFileInfo info))
|
||||
if (!FileTable.TryOpenFile(path.ToString(), out RomFileInfo info))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
@ -86,22 +84,22 @@ namespace LibHac.FsSystem.RomFs
|
||||
return BaseStorage;
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result DeleteDirectoryImpl(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result DeleteFileImpl(string path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result CreateDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result DeleteDirectoryImpl(U8Span path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result DeleteFileImpl(U8Span path) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath) => ResultFs.UnsupportedOperationModifyRomFsFileSystem.Log();
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
freeSpace = default;
|
||||
return ResultFs.UnsupportedOperationRomFsFileSystemGetSpace.Log();
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
totalSpace = default;
|
||||
return ResultFs.UnsupportedOperationRomFsFileSystemGetSpace.Log();
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
@ -16,9 +17,9 @@ namespace LibHac.FsSystem.Save
|
||||
DirectoryTable = new SaveFsList<TableEntry<SaveFindPosition>>(dirTable);
|
||||
}
|
||||
|
||||
public bool TryOpenFile(string path, out SaveFileInfo fileInfo)
|
||||
public bool TryOpenFile(U8Span path, out SaveFileInfo fileInfo)
|
||||
{
|
||||
if (!FindPathRecursive(Util.GetUtf8Bytes(path), out SaveEntryKey key))
|
||||
if (!FindPathRecursive(path, out SaveEntryKey key))
|
||||
{
|
||||
fileInfo = default;
|
||||
return false;
|
||||
@ -89,24 +90,18 @@ namespace LibHac.FsSystem.Save
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AddFile(string path, ref SaveFileInfo fileInfo)
|
||||
public void AddFile(U8Span path, ref SaveFileInfo fileInfo)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
ReadOnlySpan<byte> pathBytes = Util.GetUtf8Bytes(path);
|
||||
if (path.Length == 1 && path[0] == '/') throw new ArgumentException("Path cannot be empty");
|
||||
|
||||
if (path == "/") throw new ArgumentException("Path cannot be empty");
|
||||
|
||||
CreateFileRecursive(pathBytes, ref fileInfo);
|
||||
CreateFileRecursive(path, ref fileInfo);
|
||||
}
|
||||
|
||||
public void AddDirectory(string path)
|
||||
public void AddDirectory(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
ReadOnlySpan<byte> pathBytes = Util.GetUtf8Bytes(path);
|
||||
if (path.Length == 1 && path[0] == '/') throw new ArgumentException("Path cannot be empty");
|
||||
|
||||
if (path == "/") throw new ArgumentException("Path cannot be empty");
|
||||
|
||||
CreateDirectoryRecursive(pathBytes);
|
||||
CreateDirectoryRecursive(path);
|
||||
}
|
||||
|
||||
private void CreateFileRecursive(ReadOnlySpan<byte> path, ref SaveFileInfo fileInfo)
|
||||
@ -269,12 +264,9 @@ namespace LibHac.FsSystem.Save
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFile(string path)
|
||||
public void DeleteFile(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
ReadOnlySpan<byte> pathBytes = Util.GetUtf8Bytes(path);
|
||||
|
||||
FindPathRecursive(pathBytes, out SaveEntryKey key);
|
||||
FindPathRecursive(path, out SaveEntryKey key);
|
||||
int parentIndex = key.Parent;
|
||||
|
||||
int toDeleteIndex = FileTable.GetIndexFromKey(ref key).Index;
|
||||
@ -285,12 +277,9 @@ namespace LibHac.FsSystem.Save
|
||||
FileTable.Remove(ref key);
|
||||
}
|
||||
|
||||
public void DeleteDirectory(string path)
|
||||
public void DeleteDirectory(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
ReadOnlySpan<byte> pathBytes = Util.GetUtf8Bytes(path);
|
||||
|
||||
FindPathRecursive(pathBytes, out SaveEntryKey key);
|
||||
FindPathRecursive(path, out SaveEntryKey key);
|
||||
int parentIndex = key.Parent;
|
||||
|
||||
int toDeleteIndex = DirectoryTable.GetIndexFromKey(ref key).Index;
|
||||
@ -308,24 +297,21 @@ namespace LibHac.FsSystem.Save
|
||||
DirectoryTable.Remove(ref key);
|
||||
}
|
||||
|
||||
public void RenameFile(string srcPath, string dstPath)
|
||||
public void RenameFile(U8Span srcPath, U8Span dstPath)
|
||||
{
|
||||
if (srcPath == dstPath || TryOpenFile(dstPath, out _) || TryOpenDirectory(dstPath, out _))
|
||||
if (srcPath.Value == dstPath.Value || TryOpenFile(dstPath, out _) || TryOpenDirectory(dstPath, out _))
|
||||
{
|
||||
throw new IOException("Destination path already exists.");
|
||||
}
|
||||
|
||||
ReadOnlySpan<byte> oldPathBytes = Util.GetUtf8Bytes(srcPath);
|
||||
ReadOnlySpan<byte> newPathBytes = Util.GetUtf8Bytes(dstPath);
|
||||
|
||||
if (!FindPathRecursive(oldPathBytes, out SaveEntryKey oldKey))
|
||||
if (!FindPathRecursive(srcPath, out SaveEntryKey oldKey))
|
||||
{
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
int fileIndex = FileTable.GetIndexFromKey(ref oldKey).Index;
|
||||
|
||||
if (!FindPathRecursive(newPathBytes, out SaveEntryKey newKey))
|
||||
if (!FindPathRecursive(dstPath, out SaveEntryKey newKey))
|
||||
{
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
@ -339,29 +325,26 @@ namespace LibHac.FsSystem.Save
|
||||
FileTable.ChangeKey(ref oldKey, ref newKey);
|
||||
}
|
||||
|
||||
public Result RenameDirectory(string srcPath, string dstPath)
|
||||
public Result RenameDirectory(U8Span srcPath, U8Span dstPath)
|
||||
{
|
||||
if (srcPath == dstPath || TryOpenFile(dstPath, out _) || TryOpenDirectory(dstPath, out _))
|
||||
if (srcPath.Value == dstPath.Value || TryOpenFile(dstPath, out _) || TryOpenDirectory(dstPath, out _))
|
||||
{
|
||||
return ResultFs.PathAlreadyExists.Log();
|
||||
}
|
||||
|
||||
ReadOnlySpan<byte> oldPathBytes = Util.GetUtf8Bytes(srcPath);
|
||||
ReadOnlySpan<byte> newPathBytes = Util.GetUtf8Bytes(dstPath);
|
||||
|
||||
if (!FindPathRecursive(oldPathBytes, out SaveEntryKey oldKey))
|
||||
if (!FindPathRecursive(srcPath, out SaveEntryKey oldKey))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
int dirIndex = DirectoryTable.GetIndexFromKey(ref oldKey).Index;
|
||||
|
||||
if (!FindPathRecursive(newPathBytes, out SaveEntryKey newKey))
|
||||
if (!FindPathRecursive(dstPath, out SaveEntryKey newKey))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
if (PathTools.IsSubPath(oldPathBytes, newPathBytes))
|
||||
if (PathTools.IsSubPath(srcPath, dstPath))
|
||||
{
|
||||
return ResultFs.DestinationIsSubPathOfSource.Log();
|
||||
}
|
||||
@ -377,9 +360,9 @@ namespace LibHac.FsSystem.Save
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public bool TryOpenDirectory(string path, out SaveFindPosition position)
|
||||
public bool TryOpenDirectory(U8Span path, out SaveFindPosition position)
|
||||
{
|
||||
if (!FindPathRecursive(Util.GetUtf8Bytes(path), out SaveEntryKey key))
|
||||
if (!FindPathRecursive(path, out SaveEntryKey key))
|
||||
{
|
||||
position = default;
|
||||
return false;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
@ -7,16 +8,16 @@ namespace LibHac.FsSystem.Save
|
||||
public class SaveDataFile : FileBase
|
||||
{
|
||||
private AllocationTableStorage BaseStorage { get; }
|
||||
private string Path { get; }
|
||||
private U8String Path { get; }
|
||||
private HierarchicalSaveFileTable FileTable { get; }
|
||||
private long Size { get; set; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
public SaveDataFile(AllocationTableStorage baseStorage, string path, HierarchicalSaveFileTable fileTable, long size, OpenMode mode)
|
||||
public SaveDataFile(AllocationTableStorage baseStorage, U8Span path, HierarchicalSaveFileTable fileTable, long size, OpenMode mode)
|
||||
{
|
||||
Mode = mode;
|
||||
BaseStorage = baseStorage;
|
||||
Path = path;
|
||||
Path = path.ToU8String();
|
||||
FileTable = fileTable;
|
||||
Size = size;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using LibHac.Common;
|
||||
using LibHac.Crypto;
|
||||
using LibHac.Fs;
|
||||
|
||||
@ -143,91 +144,91 @@ namespace LibHac.FsSystem.Save
|
||||
IntegrityStorageType.Save, integrityCheckLevel, LeaveOpen);
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.CreateDirectory(path);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.CreateFile(path, size, options);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.DeleteDirectory(path);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.DeleteDirectoryRecursively(path);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.CleanDirectoryRecursively(path);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.DeleteFile(path);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.OpenDirectory(out directory, path, mode);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.OpenFile(out file, path, mode);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.RenameDirectory(oldPath, newPath);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.RenameFile(oldPath, newPath);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.GetEntryType(out entryType, path);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.GetFreeSpaceSize(out freeSpace, path);
|
||||
|
||||
return SaveResults.ConvertToExternalResult(result).LogConverted(result);
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
Result result = SaveDataFileSystemCore.GetTotalSpaceSize(out totalSpace, path);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem.Save
|
||||
@ -27,23 +28,31 @@ namespace LibHac.FsSystem.Save
|
||||
FileTable = new HierarchicalSaveFileTable(dirTableStorage, fileTableStorage);
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
FileTable.AddDirectory(path);
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
FileTable.AddDirectory(normalizedPath);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
var emptyFileEntry = new SaveFileInfo { StartBlock = int.MinValue, Length = size };
|
||||
FileTable.AddFile(path, ref emptyFileEntry);
|
||||
FileTable.AddFile(normalizedPath, ref emptyFileEntry);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
@ -58,46 +67,63 @@ namespace LibHac.FsSystem.Save
|
||||
|
||||
var fileEntry = new SaveFileInfo { StartBlock = startBlock, Length = size };
|
||||
|
||||
FileTable.AddFile(path, ref fileEntry);
|
||||
FileTable.AddFile(normalizedPath, ref fileEntry);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
FileTable.DeleteDirectory(path);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
Result rc = CleanDirectoryRecursively(path);
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
DeleteDirectory(path);
|
||||
FileTable.DeleteDirectory(normalizedPath);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
FileSystemExtensions.CleanDirectoryRecursivelyGeneric(this, path);
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = CleanDirectoryRecursively(normalizedPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = DeleteDirectory(normalizedPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
if (!FileTable.TryOpenFile(path, out SaveFileInfo fileInfo))
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
FileSystemExtensions.CleanDirectoryRecursivelyGeneric(this, normalizedPath.ToString());
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!FileTable.TryOpenFile(normalizedPath, out SaveFileInfo fileInfo))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
@ -107,17 +133,22 @@ namespace LibHac.FsSystem.Save
|
||||
AllocationTable.Free(fileInfo.StartBlock);
|
||||
}
|
||||
|
||||
FileTable.DeleteFile(path);
|
||||
FileTable.DeleteFile(normalizedPath);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (!FileTable.TryOpenDirectory(path, out SaveFindPosition position))
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!FileTable.TryOpenDirectory(normalizedPath, out SaveFindPosition position))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
@ -127,52 +158,79 @@ namespace LibHac.FsSystem.Save
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
if (!FileTable.TryOpenFile(path, out SaveFileInfo fileInfo))
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (!FileTable.TryOpenFile(normalizedPath, out SaveFileInfo fileInfo))
|
||||
{
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
AllocationTableStorage storage = OpenFatStorage(fileInfo.StartBlock);
|
||||
|
||||
file = new SaveDataFile(storage, path, FileTable, fileInfo.Length, mode);
|
||||
file = new SaveDataFile(storage, normalizedPath, FileTable, fileInfo.Length, mode);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
oldPath = PathTools.Normalize(oldPath);
|
||||
newPath = PathTools.Normalize(newPath);
|
||||
FsPath normalizedCurrentPath;
|
||||
FsPath normalizedNewPath;
|
||||
unsafe { _ = &normalizedCurrentPath; } // workaround for CS0165
|
||||
unsafe { _ = &normalizedNewPath; } // workaround for CS0165
|
||||
|
||||
return FileTable.RenameDirectory(oldPath, newPath);
|
||||
Result rc = PathTool.Normalize(normalizedCurrentPath.Str, out _, oldPath, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = PathTool.Normalize(normalizedNewPath.Str, out _, newPath, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return FileTable.RenameDirectory(normalizedCurrentPath, normalizedNewPath);
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
oldPath = PathTools.Normalize(oldPath);
|
||||
newPath = PathTools.Normalize(newPath);
|
||||
FsPath normalizedCurrentPath;
|
||||
FsPath normalizedNewPath;
|
||||
unsafe { _ = &normalizedCurrentPath; } // workaround for CS0165
|
||||
unsafe { _ = &normalizedNewPath; } // workaround for CS0165
|
||||
|
||||
FileTable.RenameFile(oldPath, newPath);
|
||||
Result rc = PathTool.Normalize(normalizedCurrentPath.Str, out _, oldPath, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = PathTool.Normalize(normalizedNewPath.Str, out _, newPath, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
FileTable.RenameFile(normalizedCurrentPath, normalizedNewPath);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
entryType = default;
|
||||
|
||||
if (FileTable.TryOpenFile(path, out SaveFileInfo _))
|
||||
FsPath normalizedPath;
|
||||
unsafe { _ = &normalizedPath; } // workaround for CS0165
|
||||
|
||||
Result rc = PathTool.Normalize(normalizedPath.Str, out _, path, false, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (FileTable.TryOpenFile(normalizedPath, out SaveFileInfo _))
|
||||
{
|
||||
entryType = DirectoryEntryType.File;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
if (FileTable.TryOpenDirectory(path, out SaveFindPosition _))
|
||||
if (FileTable.TryOpenDirectory(normalizedPath, out SaveFindPosition _))
|
||||
{
|
||||
entryType = DirectoryEntryType.Directory;
|
||||
return Result.Success;
|
||||
@ -182,7 +240,7 @@ namespace LibHac.FsSystem.Save
|
||||
return ResultFs.PathNotFound.Log();
|
||||
}
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
int freeBlockCount = AllocationTable.GetFreeListLength();
|
||||
freeSpace = Header.BlockSize * freeBlockCount;
|
||||
@ -190,7 +248,7 @@ namespace LibHac.FsSystem.Save
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
totalSpace = Header.BlockSize * Header.BlockCount;
|
||||
|
||||
@ -211,7 +269,7 @@ namespace LibHac.FsSystem.Save
|
||||
|
||||
foreach (DirectoryEntryEx file in this.EnumerateEntries("*", SearchOptions.RecurseSubdirectories))
|
||||
{
|
||||
if (FileTable.TryOpenFile(file.FullPath, out SaveFileInfo fileInfo) && fileInfo.StartBlock >= 0)
|
||||
if (FileTable.TryOpenFile(file.FullPath.ToU8Span(), out SaveFileInfo fileInfo) && fileInfo.StartBlock >= 0)
|
||||
{
|
||||
AllocationTable.FsTrimList(fileInfo.StartBlock);
|
||||
|
||||
|
@ -72,140 +72,121 @@ namespace LibHac.FsSystem
|
||||
return PathTool.Normalize(outPath.Slice(RootPath.Length - 2), out _, relativePath, PreserveUnc, false);
|
||||
}
|
||||
|
||||
protected override Result CreateDirectoryImpl(string path)
|
||||
protected override Result CreateDirectoryImpl(U8Span path)
|
||||
{
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.CreateDirectory(StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.CreateDirectory(new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
|
||||
protected override Result CreateFileImpl(U8Span path, long size, CreateFileOptions options)
|
||||
{
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.CreateFile(StringUtils.Utf8ZToString(fullPath), size, options);
|
||||
return BaseFileSystem.CreateFile(new U8Span(fullPath), size, options);
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryImpl(string path)
|
||||
protected override Result DeleteDirectoryImpl(U8Span path)
|
||||
{
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.DeleteDirectory(StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.DeleteDirectory(new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(string path)
|
||||
protected override Result DeleteDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.DeleteDirectoryRecursively(StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.DeleteDirectoryRecursively(new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result CleanDirectoryRecursivelyImpl(string path)
|
||||
protected override Result CleanDirectoryRecursivelyImpl(U8Span path)
|
||||
{
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.CleanDirectoryRecursively(StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.CleanDirectoryRecursively(new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result DeleteFileImpl(string path)
|
||||
protected override Result DeleteFileImpl(U8Span path)
|
||||
{
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.DeleteFile(StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.DeleteFile(new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
|
||||
protected override Result OpenDirectoryImpl(out IDirectory directory, U8Span path, OpenDirectoryMode mode)
|
||||
{
|
||||
directory = default;
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.OpenDirectory(out directory, StringUtils.Utf8ZToString(fullPath), mode);
|
||||
return BaseFileSystem.OpenDirectory(out directory, new U8Span(fullPath), mode);
|
||||
}
|
||||
|
||||
protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
|
||||
protected override Result OpenFileImpl(out IFile file, U8Span path, OpenMode mode)
|
||||
{
|
||||
file = default;
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.OpenFile(out file, StringUtils.Utf8ZToString(fullPath), mode);
|
||||
return BaseFileSystem.OpenFile(out file, new U8Span(fullPath), mode);
|
||||
}
|
||||
|
||||
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
|
||||
protected override Result RenameDirectoryImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
var u8OldPath = new U8String(oldPath);
|
||||
var u8NewPath = new U8String(newPath);
|
||||
|
||||
Span<byte> fullOldPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Span<byte> fullNewPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
|
||||
Result rc = ResolveFullPath(fullOldPath, u8OldPath);
|
||||
Result rc = ResolveFullPath(fullOldPath, oldPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = ResolveFullPath(fullNewPath, u8NewPath);
|
||||
rc = ResolveFullPath(fullNewPath, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.RenameDirectory(StringUtils.Utf8ZToString(fullOldPath), StringUtils.Utf8ZToString(fullNewPath));
|
||||
return BaseFileSystem.RenameDirectory(new U8Span(fullOldPath), new U8Span(fullNewPath));
|
||||
}
|
||||
|
||||
protected override Result RenameFileImpl(string oldPath, string newPath)
|
||||
protected override Result RenameFileImpl(U8Span oldPath, U8Span newPath)
|
||||
{
|
||||
var u8OldPath = new U8String(oldPath);
|
||||
var u8NewPath = new U8String(newPath);
|
||||
|
||||
Span<byte> fullOldPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Span<byte> fullNewPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
|
||||
Result rc = ResolveFullPath(fullOldPath, u8OldPath);
|
||||
Result rc = ResolveFullPath(fullOldPath, oldPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = ResolveFullPath(fullNewPath, u8NewPath);
|
||||
rc = ResolveFullPath(fullNewPath, newPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.RenameFile(StringUtils.Utf8ZToString(fullOldPath), StringUtils.Utf8ZToString(fullNewPath));
|
||||
return BaseFileSystem.RenameFile(new U8Span(fullOldPath), new U8Span(fullNewPath));
|
||||
}
|
||||
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
|
||||
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, U8Span path)
|
||||
{
|
||||
entryType = default;
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
|
||||
Result rc = ResolveFullPath(fullPath.Str, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.GetEntryType(out entryType, StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.GetEntryType(out entryType, fullPath);
|
||||
}
|
||||
|
||||
protected override Result CommitImpl()
|
||||
@ -213,51 +194,47 @@ namespace LibHac.FsSystem
|
||||
return BaseFileSystem.Commit();
|
||||
}
|
||||
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
|
||||
protected override Result GetFreeSpaceSizeImpl(out long freeSpace, U8Span path)
|
||||
{
|
||||
freeSpace = default;
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.GetFreeSpaceSize(out freeSpace, StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.GetFreeSpaceSize(out freeSpace, new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
|
||||
protected override Result GetTotalSpaceSizeImpl(out long totalSpace, U8Span path)
|
||||
{
|
||||
totalSpace = default;
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.GetTotalSpaceSize(out totalSpace, StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.GetTotalSpaceSize(out totalSpace, new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
|
||||
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, U8Span path)
|
||||
{
|
||||
timeStamp = default;
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.GetFileTimeStampRaw(out timeStamp, StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.GetFileTimeStampRaw(out timeStamp, new U8Span(fullPath));
|
||||
}
|
||||
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
|
||||
protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId,
|
||||
U8Span path)
|
||||
{
|
||||
var u8Path = new U8String(path);
|
||||
|
||||
Span<byte> fullPath = stackalloc byte[PathTools.MaxPathLength + 1];
|
||||
Result rc = ResolveFullPath(fullPath, u8Path);
|
||||
Result rc = ResolveFullPath(fullPath, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return BaseFileSystem.QueryEntry(outBuffer, inBuffer, queryId, StringUtils.Utf8ZToString(fullPath));
|
||||
return BaseFileSystem.QueryEntry(outBuffer, inBuffer, queryId, new U8Span(fullPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ namespace LibHac
|
||||
SwitchFsNca nca = null;
|
||||
try
|
||||
{
|
||||
ContentFs.OpenFile(out IFile ncaFile, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure();
|
||||
ContentFs.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
nca = new SwitchFsNca(new Nca(Keyset, ncaFile.AsStorage()));
|
||||
|
||||
@ -122,7 +122,7 @@ namespace LibHac
|
||||
|
||||
try
|
||||
{
|
||||
SaveFs.OpenFile(out IFile file, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure();
|
||||
SaveFs.OpenFile(out IFile file, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
save = new SaveDataFileSystem(Keyset, file.AsStorage(), IntegrityCheckLevel.None, true);
|
||||
}
|
||||
@ -149,7 +149,7 @@ namespace LibHac
|
||||
IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
|
||||
string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
|
||||
|
||||
fs.OpenFile(out IFile file, cnmtPath, OpenMode.Read).ThrowIfFailure();
|
||||
fs.OpenFile(out IFile file, cnmtPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
var metadata = new Cnmt(file.AsStream());
|
||||
title.Id = metadata.TitleId;
|
||||
@ -193,7 +193,7 @@ namespace LibHac
|
||||
foreach (Title title in Titles.Values.Where(x => x.ControlNca != null))
|
||||
{
|
||||
IFileSystem romfs = title.ControlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
|
||||
romfs.OpenFile(out IFile control, "control.nacp", OpenMode.Read).ThrowIfFailure();
|
||||
romfs.OpenFile(out IFile control, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
title.Control = new Nacp(control.AsStream());
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem;
|
||||
|
||||
namespace LibHac
|
||||
@ -29,7 +30,7 @@ namespace LibHac
|
||||
XciPartition root = GetRootPartition();
|
||||
if (type == XciPartitionType.Root) return root;
|
||||
|
||||
root.OpenFile(out IFile partitionFile, type.GetFileName(), OpenMode.Read).ThrowIfFailure();
|
||||
root.OpenFile(out IFile partitionFile, type.GetFileName().ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||
return new XciPartition(partitionFile.AsStorage());
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.FsSystem.NcaUtils;
|
||||
@ -34,7 +35,7 @@ namespace hactoolnet
|
||||
throw new FileNotFoundException("Specified NCA does not contain a delta fragment");
|
||||
}
|
||||
|
||||
fs.OpenFile(out IFile deltaFragmentFile, FragmentFileName, OpenMode.Read).ThrowIfFailure();
|
||||
fs.OpenFile(out IFile deltaFragmentFile, FragmentFileName.ToU8String(), OpenMode.Read).ThrowIfFailure();
|
||||
|
||||
deltaStorage = deltaFragmentFile.AsStorage();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace hactoolnet
|
||||
|
||||
try
|
||||
{
|
||||
xtsFile = new AesXtsFile(OpenMode.Read, baseFile, ctx.Options.SdPath, kekSource, validationKey, 0x4000);
|
||||
xtsFile = new AesXtsFile(OpenMode.Read, baseFile, ctx.Options.SdPath.ToU8String(), kekSource, validationKey, 0x4000);
|
||||
contentType = i;
|
||||
|
||||
break;
|
||||
|
@ -211,7 +211,7 @@ namespace hactoolnet
|
||||
IFileSystem pfs = nca.OpenFileSystem(NcaSectionType.Code, IntegrityCheckLevel.ErrorOnInvalid);
|
||||
if (!pfs.FileExists("main.npdm")) return Validity.Unchecked;
|
||||
|
||||
pfs.OpenFile(out IFile npdmFile, "main.npdm", OpenMode.Read).ThrowIfFailure();
|
||||
pfs.OpenFile(out IFile npdmFile, "main.npdm".ToU8String(), OpenMode.Read).ThrowIfFailure();
|
||||
var npdm = new NpdmBinary(npdmFile.AsStream());
|
||||
|
||||
return nca.Header.VerifySignature2(npdm.AciD.Rsa2048Modulus);
|
||||
@ -234,7 +234,7 @@ namespace hactoolnet
|
||||
PrintItem(sb, colLen, "TitleID:", $"{nca.Header.TitleId:X16}");
|
||||
if (nca.CanOpenSection(NcaSectionType.Code)) {
|
||||
IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Code, IntegrityCheckLevel.None);
|
||||
Result r = fs.OpenFile(out IFile file, "/main.npdm", OpenMode.Read);
|
||||
Result r = fs.OpenFile(out IFile file, "/main.npdm".ToU8String(), OpenMode.Read);
|
||||
if (r.IsSuccess()) {
|
||||
var npdm = new NpdmBinary(file.AsStream(), null);
|
||||
PrintItem(sb, colLen, "Title Name:", npdm.TitleName);
|
||||
|
@ -63,7 +63,7 @@ namespace hactoolnet
|
||||
|
||||
using (IFile inFile = new LocalFile(ctx.Options.ReplaceFileSource, OpenMode.Read))
|
||||
{
|
||||
save.OpenFile(out IFile outFile, destFilename, OpenMode.ReadWrite).ThrowIfFailure();
|
||||
save.OpenFile(out IFile outFile, destFilename.ToU8String(), OpenMode.ReadWrite).ThrowIfFailure();
|
||||
|
||||
using (outFile)
|
||||
{
|
||||
@ -239,7 +239,7 @@ namespace hactoolnet
|
||||
|
||||
foreach (DirectoryEntryEx entry in save.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File))
|
||||
{
|
||||
save.FileTable.TryOpenFile(entry.FullPath, out SaveFileInfo fileInfo);
|
||||
save.FileTable.TryOpenFile(entry.FullPath.ToU8Span(), out SaveFileInfo fileInfo);
|
||||
if (fileInfo.StartBlock < 0) continue;
|
||||
|
||||
IEnumerable<(int block, int length)> chain = save.AllocationTable.DumpChain(fileInfo.StartBlock);
|
||||
@ -321,7 +321,7 @@ namespace hactoolnet
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine();
|
||||
|
||||
save.GetFreeSpaceSize(out long freeSpace, "").ThrowIfFailure();
|
||||
save.GetFreeSpaceSize(out long freeSpace, "".ToU8String()).ThrowIfFailure();
|
||||
|
||||
sb.AppendLine("Savefile:");
|
||||
PrintItem(sb, colLen, "CMAC Key Used:", keyset.SaveMacKey);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -12,9 +13,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
|
||||
Assert.True(fs.CreateDirectory("/dir", NxFileAttributes.None).IsSuccess());
|
||||
Assert.True(fs.CreateDirectory("/dir".ToU8Span(), NxFileAttributes.None).IsSuccess());
|
||||
|
||||
Assert.True(fs.GetFileAttributes(out NxFileAttributes attributes, "/dir").IsSuccess());
|
||||
Assert.True(fs.GetFileAttributes(out NxFileAttributes attributes, "/dir".ToU8Span()).IsSuccess());
|
||||
Assert.Equal(NxFileAttributes.Directory, attributes);
|
||||
}
|
||||
|
||||
@ -23,9 +24,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
|
||||
Assert.True(fs.CreateDirectory("/dir", NxFileAttributes.Archive).IsSuccess());
|
||||
Assert.True(fs.CreateDirectory("/dir".ToU8Span(), NxFileAttributes.Archive).IsSuccess());
|
||||
|
||||
Assert.True(fs.GetFileAttributes(out NxFileAttributes attributes, "/dir").IsSuccess());
|
||||
Assert.True(fs.GetFileAttributes(out NxFileAttributes attributes, "/dir".ToU8Span()).IsSuccess());
|
||||
Assert.Equal(NxFileAttributes.Directory | NxFileAttributes.Archive, attributes);
|
||||
}
|
||||
|
||||
@ -33,9 +34,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
public void GetFileAttributes_AttributesOnNewFileAreEmpty()
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.GetFileAttributes(out NxFileAttributes attributes, "/file");
|
||||
Result rc = fs.GetFileAttributes(out NxFileAttributes attributes, "/file".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(NxFileAttributes.None, attributes);
|
||||
@ -45,9 +46,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
public void GetFileAttributes_AttributesOnNewDirHaveOnlyDirFlagSet()
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rc = fs.GetFileAttributes(out NxFileAttributes attributes, "/dir");
|
||||
Result rc = fs.GetFileAttributes(out NxFileAttributes attributes, "/dir".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(NxFileAttributes.Directory, attributes);
|
||||
@ -58,7 +59,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
|
||||
Result rc = fs.GetFileAttributes(out _, "/path");
|
||||
Result rc = fs.GetFileAttributes(out _, "/path".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -68,7 +69,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
|
||||
Result rc = fs.SetFileAttributes("/path", NxFileAttributes.None);
|
||||
Result rc = fs.SetFileAttributes("/path".ToU8Span(), NxFileAttributes.None);
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -77,10 +78,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
public void SetFileAttributes_SetAttributeOnFile()
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rcSet = fs.SetFileAttributes("/file", NxFileAttributes.Archive);
|
||||
Result rcGet = fs.GetFileAttributes(out NxFileAttributes attributes, "/file");
|
||||
Result rcSet = fs.SetFileAttributes("/file".ToU8Span(), NxFileAttributes.Archive);
|
||||
Result rcGet = fs.GetFileAttributes(out NxFileAttributes attributes, "/file".ToU8Span());
|
||||
|
||||
Assert.True(rcSet.IsSuccess());
|
||||
Assert.True(rcGet.IsSuccess());
|
||||
@ -91,10 +92,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
public void SetFileAttributes_SetAttributeOnDirectory()
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rcSet = fs.SetFileAttributes("/dir", NxFileAttributes.Archive);
|
||||
Result rcGet = fs.GetFileAttributes(out NxFileAttributes attributes, "/dir");
|
||||
Result rcSet = fs.SetFileAttributes("/dir".ToU8Span(), NxFileAttributes.Archive);
|
||||
Result rcGet = fs.GetFileAttributes(out NxFileAttributes attributes, "/dir".ToU8Span());
|
||||
|
||||
Assert.True(rcSet.IsSuccess());
|
||||
Assert.True(rcGet.IsSuccess());
|
||||
@ -106,9 +107,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 845, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 845, CreateFileOptions.None);
|
||||
|
||||
Assert.True(fs.GetFileSize(out long fileSize, "/file").IsSuccess());
|
||||
Assert.True(fs.GetFileSize(out long fileSize, "/file".ToU8Span()).IsSuccess());
|
||||
Assert.Equal(845, fileSize);
|
||||
}
|
||||
|
||||
@ -117,7 +118,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
|
||||
Result rc = fs.GetFileSize(out _, "/path");
|
||||
Result rc = fs.GetFileSize(out _, "/path".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -126,9 +127,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
public void GetFileSize_PathIsDirectory_ReturnsPathNotFound()
|
||||
{
|
||||
IAttributeFileSystem fs = CreateAttributeFileSystem();
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rc = fs.GetFileSize(out _, "/dir");
|
||||
Result rc = fs.GetFileSize(out _, "/dir".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,15 +11,15 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir/dir2");
|
||||
fs.CreateFile("/dir/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
fs.CreateDirectory("/dir/dir2".ToU8Span());
|
||||
fs.CreateFile("/dir/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rcDelete = fs.CleanDirectoryRecursively("/dir");
|
||||
Result rcDelete = fs.CleanDirectoryRecursively("/dir".ToU8Span());
|
||||
|
||||
Result rcDir1Type = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir");
|
||||
Result rcDir2Type = fs.GetEntryType(out _, "/dir/dir2");
|
||||
Result rcFileType = fs.GetEntryType(out _, "/dir/file1");
|
||||
Result rcDir1Type = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir".ToU8Span());
|
||||
Result rcDir2Type = fs.GetEntryType(out _, "/dir/dir2".ToU8Span());
|
||||
Result rcFileType = fs.GetEntryType(out _, "/dir/file1".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,8 +11,8 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/dir".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(DirectoryEntryType.Directory, type);
|
||||
@ -22,9 +23,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rc = fs.CreateDirectory("/dir");
|
||||
Result rc = fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathAlreadyExists.Value, rc);
|
||||
}
|
||||
@ -34,9 +35,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.CreateDirectory("/file");
|
||||
Result rc = fs.CreateDirectory("/file".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathAlreadyExists.Value, rc);
|
||||
}
|
||||
@ -46,7 +47,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Result rc = fs.CreateFile("/dir1/dir2", 0, CreateFileOptions.None);
|
||||
Result rc = fs.CreateFile("/dir1/dir2".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -56,8 +57,8 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir/");
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/dir/");
|
||||
fs.CreateDirectory("/dir/".ToU8Span());
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/dir/".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(DirectoryEntryType.Directory, type);
|
||||
@ -68,11 +69,11 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir1");
|
||||
fs.CreateDirectory("/dir2");
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
fs.CreateDirectory("/dir2".ToU8Span());
|
||||
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/dir1");
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/dir2");
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/dir1".ToU8Span());
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/dir2".ToU8Span());
|
||||
|
||||
Assert.True(rc1.IsSuccess());
|
||||
Assert.True(rc2.IsSuccess());
|
||||
@ -85,14 +86,14 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir1");
|
||||
fs.CreateDirectory("/dir2");
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
fs.CreateDirectory("/dir2".ToU8Span());
|
||||
|
||||
fs.CreateDirectory("/dir1/dir1a");
|
||||
fs.CreateDirectory("/dir2/dir2a");
|
||||
fs.CreateDirectory("/dir1/dir1a".ToU8Span());
|
||||
fs.CreateDirectory("/dir2/dir2a".ToU8Span());
|
||||
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/dir1/dir1a");
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/dir2/dir2a");
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/dir1/dir1a".ToU8Span());
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/dir2/dir2a".ToU8Span());
|
||||
|
||||
Assert.True(rc1.IsSuccess());
|
||||
Assert.True(rc2.IsSuccess());
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,8 +11,8 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/file");
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/file".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(DirectoryEntryType.File, type);
|
||||
@ -22,9 +23,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rc = fs.CreateFile("/dir", 0, CreateFileOptions.None);
|
||||
Result rc = fs.CreateFile("/dir".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Assert.Equal(ResultFs.PathAlreadyExists.Value, rc);
|
||||
}
|
||||
@ -34,9 +35,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
Result rc = fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Assert.Equal(ResultFs.PathAlreadyExists.Value, rc);
|
||||
}
|
||||
@ -46,7 +47,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Result rc = fs.CreateFile("/dir/file", 0, CreateFileOptions.None);
|
||||
Result rc = fs.CreateFile("/dir/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -56,8 +57,8 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file/", 0, CreateFileOptions.None);
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/file/");
|
||||
fs.CreateFile("/file/".ToU8Span(), 0, CreateFileOptions.None);
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/file/".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(DirectoryEntryType.File, type);
|
||||
@ -70,9 +71,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", expectedSize, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), expectedSize, CreateFileOptions.None);
|
||||
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Read);
|
||||
Result rc = file.GetSize(out long fileSize);
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
@ -84,11 +85,11 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/file1");
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/file2");
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/file1".ToU8Span());
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/file2".ToU8Span());
|
||||
|
||||
Assert.True(rc1.IsSuccess());
|
||||
Assert.True(rc2.IsSuccess());
|
||||
@ -101,14 +102,14 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir1");
|
||||
fs.CreateDirectory("/dir2");
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
fs.CreateDirectory("/dir2".ToU8Span());
|
||||
|
||||
fs.CreateFile("/dir1/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/dir2/file2", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/dir1/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/dir2/file2".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/dir1/file1");
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/dir2/file2");
|
||||
Result rc1 = fs.GetEntryType(out DirectoryEntryType type1, "/dir1/file1".ToU8Span());
|
||||
Result rc2 = fs.GetEntryType(out DirectoryEntryType type2, "/dir2/file2".ToU8Span());
|
||||
|
||||
Assert.True(rc1.IsSuccess());
|
||||
Assert.True(rc2.IsSuccess());
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,7 +11,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Result rc = fs.DeleteDirectory("/dir");
|
||||
Result rc = fs.DeleteDirectory("/dir".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -20,10 +21,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rcDelete = fs.DeleteDirectory("/dir");
|
||||
Result rcEntry = fs.GetEntryType(out _, "/dir");
|
||||
Result rcDelete = fs.DeleteDirectory("/dir".ToU8Span());
|
||||
Result rcEntry = fs.GetEntryType(out _, "/dir".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rcEntry);
|
||||
@ -34,9 +35,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.DeleteDirectory("/file");
|
||||
Result rc = fs.DeleteDirectory("/file".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -46,12 +47,12 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir1");
|
||||
fs.CreateDirectory("/dir2");
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
fs.CreateDirectory("/dir2".ToU8Span());
|
||||
|
||||
Result rcDelete = fs.DeleteDirectory("/dir2");
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir1");
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/dir2");
|
||||
Result rcDelete = fs.DeleteDirectory("/dir2".ToU8Span());
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir1".ToU8Span());
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/dir2".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
Assert.True(rcEntry1.IsSuccess());
|
||||
@ -65,12 +66,12 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir2");
|
||||
fs.CreateDirectory("/dir1");
|
||||
fs.CreateDirectory("/dir2".ToU8Span());
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
|
||||
Result rcDelete = fs.DeleteDirectory("/dir2");
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir1");
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/dir2");
|
||||
Result rcDelete = fs.DeleteDirectory("/dir2".ToU8Span());
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir1".ToU8Span());
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/dir2".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
Assert.True(rcEntry1.IsSuccess());
|
||||
@ -84,10 +85,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateFile("/dir/file", 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
fs.CreateFile("/dir/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.DeleteDirectory("/dir");
|
||||
Result rc = fs.DeleteDirectory("/dir".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.DirectoryNotEmpty.Value, rc);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,15 +11,15 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir/dir2");
|
||||
fs.CreateFile("/dir/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
fs.CreateDirectory("/dir/dir2".ToU8Span());
|
||||
fs.CreateFile("/dir/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rcDelete = fs.DeleteDirectoryRecursively("/dir");
|
||||
Result rcDelete = fs.DeleteDirectoryRecursively("/dir".ToU8Span());
|
||||
|
||||
Result rcDir1Type = fs.GetEntryType(out _, "/dir");
|
||||
Result rcDir2Type = fs.GetEntryType(out _, "/dir/dir2");
|
||||
Result rcFileType = fs.GetEntryType(out _, "/dir/file1");
|
||||
Result rcDir1Type = fs.GetEntryType(out _, "/dir".ToU8Span());
|
||||
Result rcDir2Type = fs.GetEntryType(out _, "/dir/dir2".ToU8Span());
|
||||
Result rcFileType = fs.GetEntryType(out _, "/dir/file1".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,7 +11,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Result rc = fs.DeleteFile("/file");
|
||||
Result rc = fs.DeleteFile("/file".ToU8Span());
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
|
||||
@ -19,10 +20,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rcDelete = fs.DeleteFile("/file");
|
||||
Result rcEntry = fs.GetEntryType(out _, "/file");
|
||||
Result rcDelete = fs.DeleteFile("/file".ToU8Span());
|
||||
Result rcEntry = fs.GetEntryType(out _, "/file".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rcEntry);
|
||||
@ -33,9 +34,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rc = fs.DeleteFile("/dir");
|
||||
Result rc = fs.DeleteFile("/dir".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
@ -45,12 +46,12 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rcDelete = fs.DeleteFile("/file2");
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/file1");
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/file2");
|
||||
Result rcDelete = fs.DeleteFile("/file2".ToU8Span());
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/file1".ToU8Span());
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/file2".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
Assert.True(rcEntry1.IsSuccess());
|
||||
@ -64,12 +65,12 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file2", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rcDelete = fs.DeleteFile("/file2");
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/file1");
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/file2");
|
||||
Result rcDelete = fs.DeleteFile("/file2".ToU8Span());
|
||||
Result rcEntry1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/file1".ToU8Span());
|
||||
Result rcEntry2 = fs.GetEntryType(out _, "/file2".ToU8Span());
|
||||
|
||||
Assert.True(rcDelete.IsSuccess());
|
||||
Assert.True(rcEntry1.IsSuccess());
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,9 +11,8 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Result rc = fs.GetEntryType(out DirectoryEntryType type, "/");
|
||||
Assert.Success(fs.GetEntryType(out DirectoryEntryType type, "/".ToU8Span()));
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(DirectoryEntryType.Directory, type);
|
||||
}
|
||||
|
||||
@ -21,9 +21,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Result rc = fs.GetEntryType(out _, "/path");
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
Assert.Result(ResultFs.PathNotFound, fs.GetEntryType(out _, "/path".ToU8Span()));
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
Span<DirectoryEntry> entries = stackalloc DirectoryEntry[1];
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
Assert.Success(directory.Read(out long entriesRead, entries));
|
||||
Assert.Equal(0, entriesRead);
|
||||
@ -24,7 +24,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
Assert.Success(directory.GetEntryCount(out long entryCount));
|
||||
Assert.Equal(0, entryCount);
|
||||
@ -34,13 +34,13 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
public void IDirectoryRead_AllEntriesAreReturned()
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir/dir1");
|
||||
fs.CreateFile("/dir/dir1/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/dir/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/dir/file2", 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
fs.CreateDirectory("/dir/dir1".ToU8Span());
|
||||
fs.CreateFile("/dir/dir1/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/dir/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/dir/file2".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.OpenDirectory(out IDirectory dir, "/dir", OpenDirectoryMode.All);
|
||||
Result rc = fs.OpenDirectory(out IDirectory dir, "/dir".ToU8Span(), OpenDirectoryMode.All);
|
||||
Assert.True(rc.IsSuccess());
|
||||
|
||||
var entry1 = new DirectoryEntry();
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
@ -11,10 +12,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 100, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 100, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[20];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Assert.True(file.Read(out long bytesRead, 50, buffer, ReadOption.None).IsSuccess());
|
||||
@ -27,10 +28,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Read(out _, 1, buffer, ReadOption.None);
|
||||
@ -43,10 +44,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Write);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Write);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Read(out _, 0, buffer, ReadOption.None);
|
||||
@ -59,10 +60,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Write);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Write);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Read(out _, -5, buffer, ReadOption.None);
|
||||
@ -75,10 +76,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Write);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Write);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Read(out _, long.MaxValue - 5, buffer, ReadOption.None);
|
||||
@ -91,10 +92,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 100, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 100, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[200];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Assert.True(file.Read(out long bytesRead, 90, buffer, ReadOption.None).IsSuccess());
|
||||
@ -107,10 +108,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 100, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 100, CreateFileOptions.None);
|
||||
|
||||
// The contents of a created file are undefined, so zero the file
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Write);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Write);
|
||||
using (file)
|
||||
{
|
||||
file.Write(0, new byte[100], WriteOption.None);
|
||||
@ -122,7 +123,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
var buffer = new byte[200];
|
||||
buffer.AsSpan().Fill(0xCC);
|
||||
|
||||
fs.OpenFile(out file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Assert.True(file.Read(out _, 90, buffer, ReadOption.None).IsSuccess());
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -9,13 +10,13 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
public void SetSize_FileSizeModified()
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.All);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.All);
|
||||
Result rc = file.SetSize(54321);
|
||||
file.Dispose();
|
||||
|
||||
fs.OpenFile(out file, "/file", OpenMode.All);
|
||||
fs.OpenFile(out file, "/file".ToU8Span(), OpenMode.All);
|
||||
file.GetSize(out long fileSize);
|
||||
file.Dispose();
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
@ -13,15 +14,15 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", data.Length, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), data.Length, CreateFileOptions.None);
|
||||
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Write);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Write);
|
||||
file.Write(0, data, WriteOption.None);
|
||||
file.Dispose();
|
||||
|
||||
var readData = new byte[data.Length];
|
||||
|
||||
fs.OpenFile(out file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Assert.True(file.Read(out long bytesRead, 0, readData, ReadOption.None).IsSuccess());
|
||||
@ -36,10 +37,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 10, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 10, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Write);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Write);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Write(5, buffer, WriteOption.None);
|
||||
@ -52,10 +53,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 10, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 10, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Write(5, buffer, WriteOption.None);
|
||||
@ -68,10 +69,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 10, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 10, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Write(-5, buffer, WriteOption.None);
|
||||
@ -84,10 +85,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 10, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 10, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
Result rc = file.Write(long.MaxValue - 5, buffer, WriteOption.None);
|
||||
@ -100,10 +101,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 10, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 10, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.All);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.All);
|
||||
using (file)
|
||||
{
|
||||
Assert.True(file.Write(5, buffer, WriteOption.None).IsSuccess());
|
||||
@ -118,10 +119,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 10, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 10, CreateFileOptions.None);
|
||||
|
||||
var buffer = new byte[10];
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.All);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.All);
|
||||
using (file)
|
||||
{
|
||||
Assert.True(file.Write(15, buffer, WriteOption.None).IsSuccess());
|
||||
@ -136,7 +137,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 10, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 10, CreateFileOptions.None);
|
||||
|
||||
var bufferExpected = new byte[25];
|
||||
bufferExpected.AsSpan(15).Fill(0xCC);
|
||||
@ -144,7 +145,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
var writeBuffer = new byte[10];
|
||||
writeBuffer.AsSpan().Fill(0xCC);
|
||||
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.All);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.All);
|
||||
using (file)
|
||||
{
|
||||
Assert.True(file.Write(15, writeBuffer, WriteOption.None).IsSuccess());
|
||||
@ -155,7 +156,7 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
|
||||
var readBuffer = new byte[25];
|
||||
|
||||
fs.OpenFile(out file, "/file", OpenMode.Read);
|
||||
fs.OpenFile(out file, "/file".ToU8Span(), OpenMode.Read);
|
||||
using (file)
|
||||
{
|
||||
file.Read(out _, 0, readBuffer, ReadOption.None);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,9 +11,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.OpenDirectory(out _, "/file", OpenDirectoryMode.All);
|
||||
Result rc = fs.OpenDirectory(out _, "/file".ToU8Span(), OpenDirectoryMode.All);
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,9 +11,9 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rc = fs.OpenFile(out _, "/dir", OpenMode.All);
|
||||
Result rc = fs.OpenFile(out _, "/dir".ToU8Span(), OpenMode.All);
|
||||
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,11 +11,11 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir1");
|
||||
Result rcRename = fs.RenameDirectory("/dir1", "/dir2");
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
Result rcRename = fs.RenameDirectory("/dir1".ToU8Span(), "/dir2".ToU8Span());
|
||||
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/dir2");
|
||||
Result rcDir1 = fs.GetEntryType(out _, "/dir1");
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/dir2".ToU8Span());
|
||||
Result rcDir1 = fs.GetEntryType(out _, "/dir1".ToU8Span());
|
||||
|
||||
Assert.True(rcRename.IsSuccess());
|
||||
|
||||
@ -29,21 +30,21 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir1");
|
||||
fs.CreateDirectory("/dir1/dirC");
|
||||
fs.CreateFile("/dir1/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
fs.CreateDirectory("/dir1/dirC".ToU8Span());
|
||||
fs.CreateFile("/dir1/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rcRename = fs.RenameDirectory("/dir1", "/dir2");
|
||||
Result rcRename = fs.RenameDirectory("/dir1".ToU8Span(), "/dir2".ToU8Span());
|
||||
|
||||
// Check that renamed structure exists
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/dir2");
|
||||
Result rcDirC = fs.GetEntryType(out DirectoryEntryType dir1CType, "/dir2/dirC");
|
||||
Result rcFile1 = fs.GetEntryType(out DirectoryEntryType file1Type, "/dir2/file1");
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/dir2".ToU8Span());
|
||||
Result rcDirC = fs.GetEntryType(out DirectoryEntryType dir1CType, "/dir2/dirC".ToU8Span());
|
||||
Result rcFile1 = fs.GetEntryType(out DirectoryEntryType file1Type, "/dir2/file1".ToU8Span());
|
||||
|
||||
// Check that old structure doesn't exist
|
||||
Result rcDir1 = fs.GetEntryType(out _, "/dir1");
|
||||
Result rcDirCOld = fs.GetEntryType(out _, "/dir1/dirC");
|
||||
Result rcFile1Old = fs.GetEntryType(out _, "/dir1/file1");
|
||||
Result rcDir1 = fs.GetEntryType(out _, "/dir1".ToU8Span());
|
||||
Result rcDirCOld = fs.GetEntryType(out _, "/dir1/dirC".ToU8Span());
|
||||
Result rcFile1Old = fs.GetEntryType(out _, "/dir1/file1".ToU8Span());
|
||||
|
||||
Assert.True(rcRename.IsSuccess());
|
||||
|
||||
@ -65,14 +66,14 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/parent1");
|
||||
fs.CreateDirectory("/parent2");
|
||||
fs.CreateDirectory("/parent1/dir1");
|
||||
fs.CreateDirectory("/parent1".ToU8Span());
|
||||
fs.CreateDirectory("/parent2".ToU8Span());
|
||||
fs.CreateDirectory("/parent1/dir1".ToU8Span());
|
||||
|
||||
Result rcRename = fs.RenameDirectory("/parent1/dir1", "/parent2/dir2");
|
||||
Result rcRename = fs.RenameDirectory("/parent1/dir1".ToU8Span(), "/parent2/dir2".ToU8Span());
|
||||
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/parent2/dir2");
|
||||
Result rcDir1 = fs.GetEntryType(out _, "/parent1/dir1");
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/parent2/dir2".ToU8Span());
|
||||
Result rcDir1 = fs.GetEntryType(out _, "/parent1/dir1".ToU8Span());
|
||||
|
||||
Assert.True(rcRename.IsSuccess());
|
||||
|
||||
@ -88,13 +89,13 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateDirectory("/dir1");
|
||||
fs.CreateDirectory("/dir2");
|
||||
fs.CreateDirectory("/dir1".ToU8Span());
|
||||
fs.CreateDirectory("/dir2".ToU8Span());
|
||||
|
||||
Result rcRename = fs.RenameDirectory("/dir1", "/dir2");
|
||||
Result rcRename = fs.RenameDirectory("/dir1".ToU8Span(), "/dir2".ToU8Span());
|
||||
|
||||
Result rcDir1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir1");
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/dir2");
|
||||
Result rcDir1 = fs.GetEntryType(out DirectoryEntryType dir1Type, "/dir1".ToU8Span());
|
||||
Result rcDir2 = fs.GetEntryType(out DirectoryEntryType dir2Type, "/dir2".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathAlreadyExists.Value, rcRename);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using LibHac.Fs;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
@ -10,12 +11,12 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Assert.True(fs.RenameFile("/file1", "/file2").IsSuccess());
|
||||
Assert.True(fs.RenameFile("/file1".ToU8Span(), "/file2".ToU8Span()).IsSuccess());
|
||||
|
||||
Assert.True(fs.GetEntryType(out DirectoryEntryType type, "/file2").IsSuccess());
|
||||
Result rc = fs.GetEntryType(out _, "/file1");
|
||||
Assert.True(fs.GetEntryType(out DirectoryEntryType type, "/file2".ToU8Span()).IsSuccess());
|
||||
Result rc = fs.GetEntryType(out _, "/file1".ToU8Span());
|
||||
|
||||
Assert.Equal(DirectoryEntryType.File, type);
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
@ -25,13 +26,13 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateFile("/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Assert.True(fs.RenameFile("/file1", "/dir/file2").IsSuccess());
|
||||
Assert.True(fs.RenameFile("/file1".ToU8Span(), "/dir/file2".ToU8Span()).IsSuccess());
|
||||
|
||||
Assert.True(fs.GetEntryType(out DirectoryEntryType type, "/dir/file2").IsSuccess());
|
||||
Result rc = fs.GetEntryType(out _, "/file1");
|
||||
Assert.True(fs.GetEntryType(out DirectoryEntryType type, "/dir/file2".ToU8Span()).IsSuccess());
|
||||
Result rc = fs.GetEntryType(out _, "/file1".ToU8Span());
|
||||
|
||||
Assert.Equal(DirectoryEntryType.File, type);
|
||||
Assert.Equal(ResultFs.PathNotFound.Value, rc);
|
||||
@ -42,10 +43,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file1", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2", 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file1".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2".ToU8Span(), 0, CreateFileOptions.None);
|
||||
|
||||
Result rc = fs.RenameFile("/file1", "/file2");
|
||||
Result rc = fs.RenameFile("/file1".ToU8Span(), "/file2".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathAlreadyExists.Value, rc);
|
||||
}
|
||||
@ -55,10 +56,10 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir");
|
||||
fs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
fs.CreateDirectory("/dir".ToU8Span());
|
||||
|
||||
Result rc = fs.RenameFile("/file", "/dir");
|
||||
Result rc = fs.RenameFile("/file".ToU8Span(), "/dir".ToU8Span());
|
||||
|
||||
Assert.Equal(ResultFs.PathAlreadyExists.Value, rc);
|
||||
}
|
||||
@ -68,13 +69,13 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file1", 54321, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2", 12345, CreateFileOptions.None);
|
||||
fs.CreateFile("/file1".ToU8Span(), 54321, CreateFileOptions.None);
|
||||
fs.CreateFile("/file2".ToU8Span(), 12345, CreateFileOptions.None);
|
||||
|
||||
fs.RenameFile("/file1", "/file2");
|
||||
fs.RenameFile("/file1".ToU8Span(), "/file2".ToU8Span());
|
||||
|
||||
Assert.True(fs.OpenFile(out IFile file1, "/file1", OpenMode.Read).IsSuccess());
|
||||
Assert.True(fs.OpenFile(out IFile file2, "/file2", OpenMode.Read).IsSuccess());
|
||||
Assert.True(fs.OpenFile(out IFile file1, "/file1".ToU8Span(), OpenMode.Read).IsSuccess());
|
||||
Assert.True(fs.OpenFile(out IFile file2, "/file2".ToU8Span(), OpenMode.Read).IsSuccess());
|
||||
|
||||
using (file1)
|
||||
using (file2)
|
||||
@ -94,17 +95,17 @@ namespace LibHac.Tests.Fs.IFileSystemTestBase
|
||||
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
fs.CreateFile("/file", data.Length, CreateFileOptions.None);
|
||||
fs.CreateFile("/file".ToU8Span(), data.Length, CreateFileOptions.None);
|
||||
|
||||
fs.OpenFile(out IFile file, "/file", OpenMode.Write);
|
||||
fs.OpenFile(out IFile file, "/file".ToU8Span(), OpenMode.Write);
|
||||
file.Write(0, data, WriteOption.None);
|
||||
file.Dispose();
|
||||
|
||||
fs.RenameFile("/file", "/renamed");
|
||||
fs.RenameFile("/file".ToU8Span(), "/renamed".ToU8Span());
|
||||
|
||||
var readData = new byte[data.Length];
|
||||
|
||||
fs.OpenFile(out file, "/renamed", OpenMode.Read);
|
||||
fs.OpenFile(out file, "/renamed".ToU8Span(), OpenMode.Read);
|
||||
Result rc = file.Read(out long bytesRead, 0, readData, ReadOption.None);
|
||||
file.Dispose();
|
||||
|
||||
|
@ -15,30 +15,30 @@ namespace LibHac.Tests.Fs
|
||||
|
||||
var layeredFs = new LayeredFileSystem(lowerLayerFs, upperLayerFs);
|
||||
|
||||
lowerLayerFs.CreateDirectory("/dir").ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/dir").ThrowIfFailure();
|
||||
lowerLayerFs.CreateDirectory("/dir2").ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/dir2").ThrowIfFailure();
|
||||
lowerLayerFs.CreateDirectory("/dir3").ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/dir3").ThrowIfFailure();
|
||||
lowerLayerFs.CreateDirectory("/dir".ToU8Span()).ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/dir".ToU8Span()).ThrowIfFailure();
|
||||
lowerLayerFs.CreateDirectory("/dir2".ToU8Span()).ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/dir2".ToU8Span()).ThrowIfFailure();
|
||||
lowerLayerFs.CreateDirectory("/dir3".ToU8Span()).ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/dir3".ToU8Span()).ThrowIfFailure();
|
||||
|
||||
lowerLayerFs.CreateDirectory("/lowerDir").ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/upperDir").ThrowIfFailure();
|
||||
lowerLayerFs.CreateDirectory("/lowerDir".ToU8Span()).ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/upperDir".ToU8Span()).ThrowIfFailure();
|
||||
|
||||
lowerLayerFs.CreateFile("/dir/replacedFile", 1, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir/replacedFile", 2, CreateFileOptions.None).ThrowIfFailure();
|
||||
lowerLayerFs.CreateFile("/dir/replacedFile".ToU8Span(), 1, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir/replacedFile".ToU8Span(), 2, CreateFileOptions.None).ThrowIfFailure();
|
||||
|
||||
lowerLayerFs.CreateFile("/dir2/lowerFile", 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir2/upperFile", 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
lowerLayerFs.CreateFile("/dir2/lowerFile".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir2/upperFile".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
|
||||
lowerLayerFs.CreateFile("/dir3/lowerFile", 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir3/upperFile", 2, CreateFileOptions.None).ThrowIfFailure();
|
||||
lowerLayerFs.CreateFile("/dir3/replacedFile", 1, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir3/replacedFile", 2, CreateFileOptions.None).ThrowIfFailure();
|
||||
lowerLayerFs.CreateFile("/dir3/lowerFile".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir3/upperFile".ToU8Span(), 2, CreateFileOptions.None).ThrowIfFailure();
|
||||
lowerLayerFs.CreateFile("/dir3/replacedFile".ToU8Span(), 1, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/dir3/replacedFile".ToU8Span(), 2, CreateFileOptions.None).ThrowIfFailure();
|
||||
|
||||
lowerLayerFs.CreateFile("/replacedWithDir", 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/replacedWithDir").ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/replacedWithDir/subFile", 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
lowerLayerFs.CreateFile("/replacedWithDir".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
upperLayerFs.CreateDirectory("/replacedWithDir".ToU8Span()).ThrowIfFailure();
|
||||
upperLayerFs.CreateFile("/replacedWithDir/subFile".ToU8Span(), 0, CreateFileOptions.None).ThrowIfFailure();
|
||||
|
||||
return layeredFs;
|
||||
}
|
||||
@ -56,7 +56,7 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Result(ResultFs.PathNotFound, fs.OpenFile(out _, "/fakefile", OpenMode.All));
|
||||
Assert.Result(ResultFs.PathNotFound, fs.OpenFile(out _, "/fakefile".ToU8Span(), OpenMode.All));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -64,7 +64,7 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Success(fs.OpenFile(out IFile file, "/dir/replacedFile", OpenMode.All));
|
||||
Assert.Success(fs.OpenFile(out IFile file, "/dir/replacedFile".ToU8Span(), OpenMode.All));
|
||||
Assert.Success(file.GetSize(out long fileSize));
|
||||
|
||||
Assert.Equal(2, fileSize);
|
||||
@ -75,8 +75,8 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Success(fs.OpenFile(out _, "/dir2/lowerFile", OpenMode.All));
|
||||
Assert.Success(fs.OpenFile(out _, "/dir2/upperFile", OpenMode.All));
|
||||
Assert.Success(fs.OpenFile(out _, "/dir2/lowerFile".ToU8Span(), OpenMode.All));
|
||||
Assert.Success(fs.OpenFile(out _, "/dir2/upperFile".ToU8Span(), OpenMode.All));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -84,7 +84,7 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Result(ResultFs.PathNotFound, fs.OpenDirectory(out _, "/fakedir", OpenDirectoryMode.All));
|
||||
Assert.Result(ResultFs.PathNotFound, fs.OpenDirectory(out _, "/fakedir".ToU8Span(), OpenDirectoryMode.All));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -92,7 +92,7 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory dir, "/lowerDir", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory dir, "/lowerDir".ToU8Span(), OpenDirectoryMode.All));
|
||||
Assert.Equal(typeof(InMemoryFileSystem), dir.GetType().DeclaringType);
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory dir, "/dir", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory dir, "/dir".ToU8Span(), OpenDirectoryMode.All));
|
||||
Assert.Equal(typeof(LayeredFileSystem), dir.GetType().DeclaringType);
|
||||
}
|
||||
|
||||
@ -110,8 +110,8 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Success(fs.GetEntryType(out _, "/dir2/lowerFile"));
|
||||
Assert.Success(fs.GetEntryType(out _, "/dir2/upperFile"));
|
||||
Assert.Success(fs.GetEntryType(out _, "/dir2/lowerFile".ToU8Span()));
|
||||
Assert.Success(fs.GetEntryType(out _, "/dir2/upperFile".ToU8Span()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -120,7 +120,7 @@ namespace LibHac.Tests.Fs
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
Span<DirectoryEntry> entries = stackalloc DirectoryEntry[4];
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir3", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir3".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
Assert.Success(directory.Read(out long entriesRead, entries));
|
||||
Assert.Equal(3, entriesRead);
|
||||
@ -132,7 +132,7 @@ namespace LibHac.Tests.Fs
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
var entry = new DirectoryEntry();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
Assert.Success(directory.Read(out _, SpanHelpers.AsSpan(ref entry)));
|
||||
Assert.Equal("replacedFile", StringUtils.Utf8ZToString(entry.Name));
|
||||
@ -145,7 +145,7 @@ namespace LibHac.Tests.Fs
|
||||
IFileSystem fs = CreateEmptyFileSystem();
|
||||
var entry = new DirectoryEntry();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
Assert.Success(directory.Read(out long entriesRead, SpanHelpers.AsSpan(ref entry)));
|
||||
Assert.Equal(0, entriesRead);
|
||||
@ -156,7 +156,7 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir3", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir3".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
Assert.Success(directory.GetEntryCount(out long entryCount));
|
||||
Assert.Equal(3, entryCount);
|
||||
@ -168,7 +168,7 @@ namespace LibHac.Tests.Fs
|
||||
IFileSystem fs = CreateFileSystem();
|
||||
var entry = new DirectoryEntry();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir3", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/dir3".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
// Read all entries
|
||||
long entriesRead;
|
||||
@ -186,7 +186,7 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
IFileSystem fs = CreateEmptyFileSystem();
|
||||
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/", OpenDirectoryMode.All));
|
||||
Assert.Success(fs.OpenDirectory(out IDirectory directory, "/".ToU8Span(), OpenDirectoryMode.All));
|
||||
|
||||
Assert.Success(directory.GetEntryCount(out long entryCount));
|
||||
Assert.Equal(0, entryCount);
|
||||
|
@ -16,8 +16,8 @@ namespace LibHac.Tests.Fs
|
||||
private (IFileSystem baseFs, IFileSystem subDirFs) CreateFileSystemInternal()
|
||||
{
|
||||
var baseFs = new InMemoryFileSystem();
|
||||
baseFs.CreateDirectory("/sub");
|
||||
baseFs.CreateDirectory("/sub/path");
|
||||
baseFs.CreateDirectory("/sub".ToU8Span());
|
||||
baseFs.CreateDirectory("/sub/path".ToU8Span());
|
||||
|
||||
SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem subFs, baseFs, "/sub/path".ToU8String()).ThrowIfFailure();
|
||||
return (baseFs, subFs);
|
||||
@ -28,8 +28,8 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
(IFileSystem baseFs, IFileSystem subDirFs) = CreateFileSystemInternal();
|
||||
|
||||
subDirFs.CreateFile("/file", 0, CreateFileOptions.None);
|
||||
Result rc = baseFs.GetEntryType(out DirectoryEntryType type, "/sub/path/file");
|
||||
subDirFs.CreateFile("/file".ToU8Span(), 0, CreateFileOptions.None);
|
||||
Result rc = baseFs.GetEntryType(out DirectoryEntryType type, "/sub/path/file".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(DirectoryEntryType.File, type);
|
||||
@ -40,8 +40,8 @@ namespace LibHac.Tests.Fs
|
||||
{
|
||||
(IFileSystem baseFs, IFileSystem subDirFs) = CreateFileSystemInternal();
|
||||
|
||||
subDirFs.CreateDirectory("/dir");
|
||||
Result rc = baseFs.GetEntryType(out DirectoryEntryType type, "/sub/path/dir");
|
||||
subDirFs.CreateDirectory("/dir".ToU8Span());
|
||||
Result rc = baseFs.GetEntryType(out DirectoryEntryType type, "/sub/path/dir".ToU8Span());
|
||||
|
||||
Assert.True(rc.IsSuccess());
|
||||
Assert.Equal(DirectoryEntryType.Directory, type);
|
||||
|
Loading…
x
Reference in New Issue
Block a user