Use U8Span more in FilleSystemClient

This commit is contained in:
Alex Barney 2020-03-09 00:06:39 -07:00
parent c141b72912
commit 328968c630
13 changed files with 169 additions and 139 deletions

View File

@ -46,6 +46,18 @@ namespace LibHac.Common
return StringUtils.Utf8ZToString(_buffer);
}
public bool IsEmpty() => _buffer == null || _buffer.Length == 0;
/// <summary>
/// Checks if the <see cref="U8String"/> has no buffer.
/// </summary>
/// <returns><see langword="true"/> if the string has no buffer.
/// Otherwise, <see langword="false"/>.</returns>
public bool IsNull() => _buffer == null;
/// <summary>
/// Checks if the <see cref="U8String"/> has no buffer or begins with a null terminator.
/// </summary>
/// <returns><see langword="true"/> if the string has no buffer or begins with a null terminator.
/// Otherwise, <see langword="false"/>.</returns>
public bool IsEmpty() => _buffer == null || _buffer.Length < 1 || _buffer[0] == 0;
}
}

View File

@ -105,9 +105,9 @@ namespace LibHac.Fs
return IsEnabledAccessLog(AccessLogTarget.All);
}
internal bool IsEnabledFileSystemAccessorAccessLog(string mountName)
internal bool IsEnabledFileSystemAccessorAccessLog(U8Span mountName)
{
if (MountTable.Find(mountName, out FileSystemAccessor accessor).IsFailure())
if (MountTable.Find(mountName.ToString(), out FileSystemAccessor accessor).IsFailure())
{
return true;
}

View File

@ -6,9 +6,9 @@ namespace LibHac.Fs
{
public partial class FileSystemClient
{
public Result CreateDirectory(string path)
public Result CreateDirectory(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -17,7 +17,7 @@ namespace LibHac.Fs
rc = fileSystem.CreateDirectory(subPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
@ -27,14 +27,14 @@ namespace LibHac.Fs
return rc;
}
public Result CreateFile(string path, long size)
public Result CreateFile(U8Span path, long size)
{
return CreateFile(path, size, CreateFileOptions.None);
}
public Result CreateFile(string path, long size, CreateFileOptions options)
public Result CreateFile(U8Span path, long size, CreateFileOptions options)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -43,7 +43,7 @@ namespace LibHac.Fs
rc = fileSystem.CreateFile(subPath, size, options);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\", size: {size}");
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\", size: {size}");
}
else
{
@ -53,9 +53,9 @@ namespace LibHac.Fs
return rc;
}
public Result DeleteDirectory(string path)
public Result DeleteDirectory(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -64,7 +64,7 @@ namespace LibHac.Fs
rc = fileSystem.DeleteDirectory(subPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
@ -74,9 +74,9 @@ namespace LibHac.Fs
return rc;
}
public Result DeleteDirectoryRecursively(string path)
public Result DeleteDirectoryRecursively(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -85,7 +85,7 @@ namespace LibHac.Fs
rc = fileSystem.DeleteDirectoryRecursively(subPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
@ -95,9 +95,9 @@ namespace LibHac.Fs
return rc;
}
public Result CleanDirectoryRecursively(string path)
public Result CleanDirectoryRecursively(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -106,7 +106,7 @@ namespace LibHac.Fs
rc = fileSystem.CleanDirectoryRecursively(subPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
@ -116,9 +116,9 @@ namespace LibHac.Fs
return rc;
}
public Result DeleteFile(string path)
public Result DeleteFile(U8Span path)
{
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -127,7 +127,7 @@ namespace LibHac.Fs
rc = fileSystem.DeleteFile(subPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
@ -137,12 +137,12 @@ namespace LibHac.Fs
return rc;
}
public Result RenameDirectory(string oldPath, string newPath)
public Result RenameDirectory(U8Span oldPath, U8Span newPath)
{
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath);
if (rc.IsFailure()) return rc;
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath.ToU8Span());
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath);
if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
@ -156,7 +156,7 @@ namespace LibHac.Fs
rc = oldFileSystem.RenameDirectory(oldSubPath, newSubPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath.ToString()}\", new_path: \"{newPath.ToString()}\"");
}
else
{
@ -166,12 +166,12 @@ namespace LibHac.Fs
return rc;
}
public Result RenameFile(string oldPath, string newPath)
public Result RenameFile(U8Span oldPath, U8Span newPath)
{
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor oldFileSystem, out U8Span oldSubPath, oldPath);
if (rc.IsFailure()) return rc;
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath.ToU8Span());
rc = FindFileSystem(out FileSystemAccessor newFileSystem, out U8Span newSubPath, newPath);
if (rc.IsFailure()) return rc;
if (oldFileSystem != newFileSystem)
@ -185,7 +185,7 @@ namespace LibHac.Fs
rc = oldFileSystem.RenameFile(oldSubPath, newSubPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath}\", new_path: \"{newPath}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{oldPath.ToString()}\", new_path: \"{newPath.ToString()}\"");
}
else
{
@ -195,11 +195,11 @@ namespace LibHac.Fs
return rc;
}
public Result GetEntryType(out DirectoryEntryType type, string path)
public Result GetEntryType(out DirectoryEntryType type, U8Span path)
{
type = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -208,7 +208,7 @@ namespace LibHac.Fs
rc = fileSystem.GetEntryType(out type, subPath);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", path: \"{path}\"");
OutputAccessLog(rc, startTime, endTime, $", path: \"{path.ToString()}\"");
}
else
{
@ -218,11 +218,11 @@ namespace LibHac.Fs
return rc;
}
public Result OpenFile(out FileHandle handle, string path, OpenMode mode)
public Result OpenFile(out FileHandle handle, U8Span path, OpenMode mode)
{
handle = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -232,7 +232,7 @@ namespace LibHac.Fs
handle = new FileHandle(file);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path}\", open_mode: {mode}");
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path.ToString()}\", open_mode: {mode}");
}
else
{
@ -243,11 +243,11 @@ namespace LibHac.Fs
return rc;
}
public Result OpenDirectory(out DirectoryHandle handle, string path, OpenDirectoryMode mode)
public Result OpenDirectory(out DirectoryHandle handle, U8Span path, OpenDirectoryMode mode)
{
handle = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -257,7 +257,7 @@ namespace LibHac.Fs
handle = new DirectoryHandle(dir);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path}\", open_mode: {mode}");
OutputAccessLog(rc, startTime, endTime, handle, $", path: \"{path.ToString()}\", open_mode: {mode}");
}
else
{
@ -268,39 +268,39 @@ namespace LibHac.Fs
return rc;
}
public Result GetFreeSpaceSize(out long freeSpace, string path)
public Result GetFreeSpaceSize(out long freeSpace, U8Span path)
{
freeSpace = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
return fileSystem.GetFreeSpaceSize(out freeSpace, subPath);
}
public Result GetTotalSpaceSize(out long totalSpace, string path)
public Result GetTotalSpaceSize(out long totalSpace, U8Span path)
{
totalSpace = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
return fileSystem.GetTotalSpaceSize(out totalSpace, subPath);
}
public Result GetFileTimeStamp(out FileTimeStampRaw timeStamp, string path)
public Result GetFileTimeStamp(out FileTimeStampRaw timeStamp, U8Span path)
{
timeStamp = default;
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path.ToU8Span());
Result rc = FindFileSystem(out FileSystemAccessor fileSystem, out U8Span subPath, path);
if (rc.IsFailure()) return rc;
return fileSystem.GetFileTimeStampRaw(out timeStamp, subPath);
}
public Result Commit(string mountName)
public Result Commit(U8Span mountName)
{
Result rc = MountTable.Find(mountName, out FileSystemAccessor fileSystem);
Result rc = MountTable.Find(mountName.ToString(), out FileSystemAccessor fileSystem);
if (rc.IsFailure()) return rc;
if (IsEnabledAccessLog() && fileSystem.IsAccessLogEnabled)
@ -309,7 +309,7 @@ namespace LibHac.Fs
rc = fileSystem.Commit();
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountName}\"");
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountName.ToString()}\"");
}
else
{

View File

@ -78,22 +78,23 @@ namespace LibHac.Fs
return Result.Success;
}
public void Unmount(string mountName)
public void Unmount(U8Span mountName)
{
Result rc;
string mountNameStr = mountName.ToString();
if (IsEnabledAccessLog() && IsEnabledFileSystemAccessorAccessLog(mountName))
{
TimeSpan startTime = Time.GetCurrent();
rc = MountTable.Unmount(mountName);
rc = MountTable.Unmount(mountNameStr);
TimeSpan endTime = Time.GetCurrent();
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountName}\"");
OutputAccessLog(rc, startTime, endTime, $", name: \"{mountNameStr}\"");
}
else
{
rc = MountTable.Unmount(mountName);
rc = MountTable.Unmount(mountNameStr);
}
rc.ThrowIfFailure();

View File

@ -12,7 +12,7 @@ namespace LibHac.Fs
public static Result CopyDirectory(this FileSystemClient fs, string sourcePath, string destPath,
CreateFileOptions options = CreateFileOptions.None, IProgressReport logger = null)
{
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All);
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All);
if (rc.IsFailure()) return rc;
using (sourceHandle)
@ -46,12 +46,12 @@ namespace LibHac.Fs
public static Result CopyFile(this FileSystemClient fs, string sourcePath, string destPath, IProgressReport logger = null)
{
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath.ToU8Span(), OpenMode.Read);
if (rc.IsFailure()) return rc;
using (sourceHandle)
{
rc = fs.OpenFile(out FileHandle destHandle, destPath, OpenMode.Write | OpenMode.AllowAppend);
rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend);
if (rc.IsFailure()) return rc;
using (destHandle)
@ -111,7 +111,7 @@ namespace LibHac.Fs
bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive);
bool recurse = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories);
fs.OpenDirectory(out DirectoryHandle sourceHandle, path, OpenDirectoryMode.All).ThrowIfFailure();
fs.OpenDirectory(out DirectoryHandle sourceHandle, path.ToU8Span(), OpenDirectoryMode.All).ThrowIfFailure();
using (sourceHandle)
{
@ -144,14 +144,14 @@ namespace LibHac.Fs
public static bool DirectoryExists(this FileSystemClient 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 FileSystemClient 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);
}
@ -189,25 +189,30 @@ namespace LibHac.Fs
{
string subPath = path.Substring(0, i);
fs.CreateDirectory(subPath);
fs.CreateDirectory(subPath.ToU8Span());
}
}
fs.CreateDirectory(path);
fs.CreateDirectory(path.ToU8Span());
}
public static void CreateOrOverwriteFile(this FileSystemClient fs, string path, long size)
public static Result CreateOrOverwriteFile(this FileSystemClient fs, string path, long size)
{
fs.CreateOrOverwriteFile(path, size, CreateFileOptions.None);
return fs.CreateOrOverwriteFile(path, size, CreateFileOptions.None);
}
public static void CreateOrOverwriteFile(this FileSystemClient fs, string path, long size, CreateFileOptions options)
public static Result CreateOrOverwriteFile(this FileSystemClient fs, string path, long size, CreateFileOptions options)
{
path = PathTools.Normalize(path);
var u8Path = path.ToU8Span();
if (fs.FileExists(path)) fs.DeleteFile(path);
if (fs.FileExists(path))
{
Result rc = fs.DeleteFile(u8Path);
if (rc.IsFailure()) return rc;
}
fs.CreateFile(path, size, CreateFileOptions.None);
return fs.CreateFile(u8Path, size, CreateFileOptions.None);
}
internal static bool IsEnabledFileSystemAccessorAccessLog(this FileSystemClient fs, string mountName)

View File

@ -18,7 +18,7 @@ namespace LibHac.FsService
private const long LastIdFileSize = 8;
private FileSystemClient FsClient { get; }
private string MountName { get; }
private U8String MountName { get; }
private ulong SaveDataId { get; }
private SaveDataSpaceId SpaceId { get; }
private KeyValueDatabase<SaveDataAttribute> KvDatabase { get; set; }
@ -29,10 +29,10 @@ namespace LibHac.FsService
private int Version { get; set; }
private List<SaveDataInfoReader> OpenedReaders { get; } = new List<SaveDataInfoReader>();
public SaveDataIndexer(FileSystemClient fsClient, string mountName, SaveDataSpaceId spaceId, ulong saveDataId)
public SaveDataIndexer(FileSystemClient fsClient, U8Span mountName, SaveDataSpaceId spaceId, ulong saveDataId)
{
FsClient = fsClient;
MountName = mountName;
MountName = mountName.ToU8String();
SaveDataId = saveDataId;
SpaceId = spaceId;
Version = 1;
@ -77,7 +77,7 @@ namespace LibHac.FsService
string idFilePath = $"{MountName}:/{LastIdFileName}";
rc = FsClient.OpenFile(out FileHandle handle, idFilePath, OpenMode.Write);
rc = FsClient.OpenFile(out FileHandle handle, idFilePath.ToU8Span(), OpenMode.Write);
if (rc.IsFailure()) return rc;
bool fileAlreadyClosed = false;
@ -423,7 +423,7 @@ namespace LibHac.FsService
string dbDirectory = $"{MountName}:/";
rc = FsClient.GetEntryType(out DirectoryEntryType entryType, dbDirectory);
rc = FsClient.GetEntryType(out DirectoryEntryType entryType, dbDirectory.ToU8Span());
if (rc.IsFailure()) return rc;
if (entryType == DirectoryEntryType.File)
@ -431,7 +431,7 @@ namespace LibHac.FsService
string dbArchiveFile = $"{dbDirectory}imkvdb.arc";
KvDatabase = new KeyValueDatabase<SaveDataAttribute>(FsClient, dbArchiveFile);
KvDatabase = new KeyValueDatabase<SaveDataAttribute>(FsClient, dbArchiveFile.ToU8Span());
IsInitialized = true;
return Result.Success;
@ -466,7 +466,7 @@ namespace LibHac.FsService
if (rc.IsFailure()) return rc;
bool createdNewFile = false;
string idFilePath = $"{MountName}:/{LastIdFileName}";
var idFilePath = $"{MountName}:/{LastIdFileName}".ToU8String();
rc = FsClient.OpenFile(out FileHandle handle, idFilePath, OpenMode.Read);
@ -572,10 +572,10 @@ namespace LibHac.FsService
private ref struct Mounter
{
private FileSystemClient FsClient { get; set; }
private string MountName { get; set; }
private U8String MountName { get; set; }
private bool IsMounted { get; set; }
public Result Initialize(FileSystemClient fsClient, string mountName, SaveDataSpaceId spaceId,
public Result Initialize(FileSystemClient fsClient, U8String mountName, SaveDataSpaceId spaceId,
ulong saveDataId)
{
FsClient = fsClient;
@ -583,7 +583,7 @@ namespace LibHac.FsService
FsClient.DisableAutoSaveDataCreation();
Result rc = FsClient.MountSystemSaveData(MountName.ToU8Span(), spaceId, saveDataId);
Result rc = FsClient.MountSystemSaveData(MountName, spaceId, saveDataId);
if (rc.IsFailure())
{
@ -592,7 +592,7 @@ namespace LibHac.FsService
rc = FsClient.CreateSystemSaveData(spaceId, saveDataId, TitleId.Zero, 0xC0000, 0xC0000, 0);
if (rc.IsFailure()) return rc;
rc = FsClient.MountSystemSaveData(MountName.ToU8Span(), spaceId, saveDataId);
rc = FsClient.MountSystemSaveData(MountName, spaceId, saveDataId);
if (rc.IsFailure()) return rc;
}
else
@ -608,7 +608,7 @@ namespace LibHac.FsService
rc = FsClient.CreateSystemSaveData(spaceId, saveDataId, TitleId.Zero, 0xC0000, 0xC0000, 0);
if (rc.IsFailure()) return rc;
rc = FsClient.MountSystemSaveData(MountName.ToU8Span(), spaceId, saveDataId);
rc = FsClient.MountSystemSaveData(MountName, spaceId, saveDataId);
if (rc.IsFailure()) return rc;
}
}

View File

@ -1,4 +1,5 @@
using System.Threading;
using LibHac.Common;
using LibHac.Fs;
namespace LibHac.FsService
@ -30,7 +31,7 @@ namespace LibHac.FsService
if (!_bisIndexer.IsInitialized)
{
_bisIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDb", SaveDataSpaceId.System, SaveDataId);
_bisIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDb".ToU8Span(), SaveDataSpaceId.System, SaveDataId);
}
reader = new SaveDataIndexerReader(_bisIndexer.Indexer, _bisIndexer.Locker);
@ -44,7 +45,7 @@ namespace LibHac.FsService
if (!_sdCardIndexer.IsInitialized)
{
_sdCardIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSd", SaveDataSpaceId.SdSystem, SaveDataId);
_sdCardIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSd".ToU8Span(), SaveDataSpaceId.SdSystem, SaveDataId);
}
reader = new SaveDataIndexerReader(_sdCardIndexer.Indexer, _sdCardIndexer.Locker);
@ -66,7 +67,7 @@ namespace LibHac.FsService
if (!_safeIndexer.IsInitialized)
{
_safeIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbPr", SaveDataSpaceId.ProperSystem, SaveDataId);
_safeIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbPr".ToU8Span(), SaveDataSpaceId.ProperSystem, SaveDataId);
}
reader = new SaveDataIndexerReader(_safeIndexer.Indexer, _safeIndexer.Locker);
@ -77,7 +78,7 @@ namespace LibHac.FsService
if (!_properSystemIndexer.IsInitialized)
{
_properSystemIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSf", SaveDataSpaceId.SafeMode, SaveDataId);
_properSystemIndexer.Indexer = new SaveDataIndexer(FsClient, "saveDataIxrDbSf".ToU8Span(), SaveDataSpaceId.SafeMode, SaveDataId);
}
reader = new SaveDataIndexerReader(_properSystemIndexer.Indexer, _properSystemIndexer.Locker);

View File

@ -13,16 +13,16 @@ namespace LibHac.Kvdb
private Dictionary<TKey, byte[]> KvDict { get; } = new Dictionary<TKey, byte[]>();
private FileSystemClient FsClient { get; }
private string FileName { get; }
private U8String FileName { get; }
public int Count => KvDict.Count;
public KeyValueDatabase() { }
public KeyValueDatabase(FileSystemClient fsClient, string fileName)
public KeyValueDatabase(FileSystemClient fsClient, U8Span fileName)
{
FsClient = fsClient;
FileName = fileName;
FileName = fileName.ToU8String();
}
public Result Get(ref TKey key, Span<byte> valueBuffer)
@ -109,7 +109,7 @@ namespace LibHac.Kvdb
public Result ReadDatabaseFromFile()
{
if (FsClient == null || FileName == null)
if (FsClient == null || FileName.IsNull())
return ResultFs.PreconditionViolation.Log();
Result rc = ReadFile(out byte[] data);
@ -124,7 +124,7 @@ namespace LibHac.Kvdb
public Result WriteDatabaseToFile()
{
if (FsClient == null || FileName == null)
if (FsClient == null || FileName.IsNull())
return ResultFs.PreconditionViolation.Log();
var buffer = new byte[GetExportedSize()];
@ -157,7 +157,7 @@ namespace LibHac.Kvdb
private Result ReadFile(out byte[] data)
{
Debug.Assert(FsClient != null);
Debug.Assert(!string.IsNullOrWhiteSpace(FileName));
Debug.Assert(!FileName.IsEmpty());
data = default;
@ -180,7 +180,7 @@ namespace LibHac.Kvdb
private Result WriteFile(ReadOnlySpan<byte> data)
{
Debug.Assert(FsClient != null);
Debug.Assert(!string.IsNullOrWhiteSpace(FileName));
Debug.Assert(!FileName.IsEmpty());
FsClient.DeleteFile(FileName);

View File

@ -1,6 +1,7 @@
using System;
using System.Buffers;
using LibHac;
using LibHac.Common;
using LibHac.Fs;
using LibHac.FsSystem;
@ -8,14 +9,14 @@ namespace hactoolnet
{
public static class FsUtils
{
public static void CopyDirectoryWithProgress(FileSystemClient fs, string sourcePath, string destPath,
public static Result CopyDirectoryWithProgress(FileSystemClient fs, U8Span sourcePath, U8Span destPath,
CreateFileOptions options = CreateFileOptions.None, IProgressReport logger = null)
{
try
{
logger?.SetTotal(GetTotalSize(fs, sourcePath));
CopyDirectoryWithProgressInternal(fs, sourcePath, destPath, options, logger);
return CopyDirectoryWithProgressInternal(fs, sourcePath, destPath, options, logger);
}
finally
{
@ -23,41 +24,51 @@ namespace hactoolnet
}
}
private static void CopyDirectoryWithProgressInternal(FileSystemClient fs, string sourcePath, string destPath,
private static Result CopyDirectoryWithProgressInternal(FileSystemClient fs, U8Span sourcePath, U8Span destPath,
CreateFileOptions options, IProgressReport logger)
{
fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All).ThrowIfFailure();
string sourcePathStr = sourcePath.ToString();
string destPathStr = destPath.ToString();
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath, OpenDirectoryMode.All);
if (rc.IsFailure()) return rc;
using (sourceHandle)
{
foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePath, "*", SearchOptions.Default))
foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePathStr, "*", SearchOptions.Default))
{
string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name));
string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name));
string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePathStr, entry.Name));
string subDstPath = PathTools.Normalize(PathTools.Combine(destPathStr, entry.Name));
if (entry.Type == DirectoryEntryType.Directory)
{
fs.EnsureDirectoryExists(subDstPath);
CopyDirectoryWithProgressInternal(fs, subSrcPath, subDstPath, options, logger);
rc = CopyDirectoryWithProgressInternal(fs, subSrcPath.ToU8Span(), subDstPath.ToU8Span(), options, logger);
if (rc.IsFailure()) return rc;
}
if (entry.Type == DirectoryEntryType.File)
{
logger?.LogMessage(subSrcPath);
fs.CreateOrOverwriteFile(subDstPath, entry.Size, options);
CopyFileWithProgress(fs, subSrcPath, subDstPath, logger);
rc = fs.CreateOrOverwriteFile(subDstPath, entry.Size, options);
if (rc.IsFailure()) return rc;
rc = CopyFileWithProgress(fs, subSrcPath.ToU8Span(), subDstPath.ToU8Span(), logger);
if (rc.IsFailure()) return rc;
}
}
}
return Result.Success;
}
public static long GetTotalSize(FileSystemClient fs, string path, string searchPattern = "*")
public static long GetTotalSize(FileSystemClient fs, U8Span path, string searchPattern = "*")
{
long size = 0;
foreach (DirectoryEntryEx entry in fs.EnumerateEntries(path, searchPattern))
foreach (DirectoryEntryEx entry in fs.EnumerateEntries(path.ToString(), searchPattern))
{
size += entry.Size;
}
@ -65,7 +76,7 @@ namespace hactoolnet
return size;
}
public static Result CopyFileWithProgress(FileSystemClient fs, string sourcePath, string destPath, IProgressReport logger = null)
public static Result CopyFileWithProgress(FileSystemClient fs, U8Span sourcePath, U8Span destPath, IProgressReport logger = null)
{
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);
if (rc.IsFailure()) return rc;

View File

@ -51,10 +51,10 @@ namespace hactoolnet
fs.Register(mountName.ToU8Span(), OpenFileSystem(i));
fs.Register("output".ToU8Span(), new LocalFileSystem(ctx.Options.SectionOutDir[i]));
FsUtils.CopyDirectoryWithProgress(fs, mountName + ":/", "output:/", logger: ctx.Logger);
FsUtils.CopyDirectoryWithProgress(fs, (mountName + ":/").ToU8Span(), "output:/".ToU8Span(), logger: ctx.Logger).ThrowIfFailure();
fs.Unmount(mountName);
fs.Unmount("output");
fs.Unmount(mountName.ToU8Span());
fs.Unmount("output".ToU8Span());
}
if (ctx.Options.Validate && nca.SectionExists(i))
@ -100,10 +100,10 @@ namespace hactoolnet
fs.Register("rom".ToU8Span(), OpenFileSystemByType(NcaSectionType.Data));
fs.Register("output".ToU8Span(), new LocalFileSystem(ctx.Options.RomfsOutDir));
FsUtils.CopyDirectoryWithProgress(fs, "rom:/", "output:/", logger: ctx.Logger);
FsUtils.CopyDirectoryWithProgress(fs, "rom:/".ToU8Span(), "output:/".ToU8Span(), logger: ctx.Logger).ThrowIfFailure();
fs.Unmount("rom");
fs.Unmount("output");
fs.Unmount("rom".ToU8Span());
fs.Unmount("output".ToU8Span());
}
if (ctx.Options.ReadBench)
@ -157,10 +157,10 @@ namespace hactoolnet
fs.Register("code".ToU8Span(), OpenFileSystemByType(NcaSectionType.Code));
fs.Register("output".ToU8Span(), new LocalFileSystem(ctx.Options.ExefsOutDir));
FsUtils.CopyDirectoryWithProgress(fs, "code:/", "output:/", logger: ctx.Logger);
FsUtils.CopyDirectoryWithProgress(fs, "code:/".ToU8Span(), "output:/".ToU8Span(), logger: ctx.Logger).ThrowIfFailure();
fs.Unmount("code");
fs.Unmount("output");
fs.Unmount("code".ToU8Span());
fs.Unmount("output".ToU8Span());
}
}

View File

@ -42,9 +42,9 @@ namespace hactoolnet
{
fs.Register("output".ToU8Span(), new LocalFileSystem(ctx.Options.OutDir));
FsUtils.CopyDirectoryWithProgress(fs, "save:/", "output:/", logger: ctx.Logger);
FsUtils.CopyDirectoryWithProgress(fs, "save:/".ToU8Span(), "output:/".ToU8Span(), logger: ctx.Logger).ThrowIfFailure();
fs.Unmount("output");
fs.Unmount("output".ToU8Span());
}
if (ctx.Options.DebugOutDir != null)
@ -88,13 +88,13 @@ namespace hactoolnet
{
fs.Register("input".ToU8Span(), new LocalFileSystem(ctx.Options.RepackSource));
fs.CleanDirectoryRecursively("save:/");
fs.Commit("save");
fs.CleanDirectoryRecursively("save:/".ToU8Span());
fs.Commit("save".ToU8Span());
FsUtils.CopyDirectoryWithProgress(fs, "input:/", "save:/", logger: ctx.Logger);
FsUtils.CopyDirectoryWithProgress(fs, "input:/".ToU8Span(), "save:/".ToU8Span(), logger: ctx.Logger).ThrowIfFailure();
fs.Commit("save");
fs.Unmount("input");
fs.Commit("save".ToU8Span());
fs.Unmount("input".ToU8Span());
signNeeded = true;
}
@ -134,7 +134,7 @@ namespace hactoolnet
ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?");
}
fs.Unmount("save");
fs.Unmount("save".ToU8Span());
return;
}
@ -149,7 +149,7 @@ namespace hactoolnet
ctx.Logger.LogMessage(save.Print(ctx.Keyset));
//ctx.Logger.LogMessage(PrintFatLayout(save.SaveDataFileSystemCore));
fs.Unmount("save");
fs.Unmount("save".ToU8Span());
}
}

View File

@ -16,7 +16,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests.ShimTests
fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId, 0, 0, SaveDataFlags.None);
Assert.Success(fs.MountCacheStorage("cache".ToU8String(), applicationId));
Assert.Success(fs.MountCacheStorage("cache".ToU8Span(), applicationId));
}
[Fact]
@ -26,14 +26,14 @@ namespace LibHac.Tests.Fs.FileSystemClientTests.ShimTests
FileSystemClient fs = FileSystemServerFactory.CreateClient(true);
fs.CreateCacheStorage(applicationId, SaveDataSpaceId.SdCache, applicationId, 0, 0, SaveDataFlags.None);
fs.MountCacheStorage("cache".ToU8String(), applicationId);
fs.MountCacheStorage("cache".ToU8Span(), applicationId);
fs.CreateFile("cache:/file", 0);
fs.Commit("cache");
fs.Unmount("cache");
fs.CreateFile("cache:/file".ToU8Span(), 0);
fs.Commit("cache".ToU8Span());
fs.Unmount("cache".ToU8Span());
Assert.Success(fs.MountCacheStorage("cache".ToU8String(), applicationId));
Assert.Success(fs.GetEntryType(out DirectoryEntryType type, "cache:/file"));
Assert.Success(fs.MountCacheStorage("cache".ToU8Span(), applicationId));
Assert.Success(fs.GetEntryType(out DirectoryEntryType type, "cache:/file".ToU8Span()));
Assert.Equal(DirectoryEntryType.File, type);
}
[Fact]
@ -43,25 +43,25 @@ namespace LibHac.Tests.Fs.FileSystemClientTests.ShimTests
FileSystemClient fs = FileSystemServerFactory.CreateClient(true);
fs.CreateCacheStorage(applicationId, SaveDataSpaceId.SdCache, applicationId, 0, 0, SaveDataFlags.None);
fs.MountCacheStorage("cache".ToU8String(), applicationId);
fs.CreateFile("cache:/sd", 0);
fs.Commit("cache");
fs.Unmount("cache");
fs.MountCacheStorage("cache".ToU8Span(), applicationId);
fs.CreateFile("cache:/sd".ToU8Span(), 0);
fs.Commit("cache".ToU8Span());
fs.Unmount("cache".ToU8Span());
// Turn off the SD card so the User save is mounted
fs.SetSdCardAccessibility(false);
fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId, 0, 0, SaveDataFlags.None);
fs.MountCacheStorage("cache".ToU8String(), applicationId);
fs.CreateFile("cache:/bis", 0);
fs.Commit("cache");
fs.Unmount("cache");
fs.MountCacheStorage("cache".ToU8Span(), applicationId);
fs.CreateFile("cache:/bis".ToU8Span(), 0);
fs.Commit("cache".ToU8Span());
fs.Unmount("cache".ToU8Span());
fs.SetSdCardAccessibility(true);
Assert.Success(fs.MountCacheStorage("cache".ToU8String(), applicationId));
Assert.Success(fs.GetEntryType(out _, "cache:/sd"));
Assert.Failure(fs.GetEntryType(out _, "cache:/bis"));
Assert.Success(fs.GetEntryType(out _, "cache:/sd".ToU8Span()));
Assert.Failure(fs.GetEntryType(out _, "cache:/bis".ToU8Span()));
}
}
}

View File

@ -12,7 +12,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests.ShimTests
{
FileSystemClient fs = FileSystemServerFactory.CreateClient(true);
Assert.Success(fs.MountSdCard("sdcard".ToU8String()));
Assert.Success(fs.MountSdCard("sdcard".ToU8Span()));
}
[Fact]
@ -20,7 +20,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests.ShimTests
{
FileSystemClient fs = FileSystemServerFactory.CreateClient(false);
Assert.Result(ResultFs.SdCardNotFound, fs.MountSdCard("sdcard".ToU8String()));
Assert.Result(ResultFs.SdCardNotFound, fs.MountSdCard("sdcard".ToU8Span()));
}
[Fact]
@ -30,7 +30,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests.ShimTests
fs.MountSdCard("sdcard".ToU8String());
Assert.Success(fs.CreateFile("sdcard:/file", 100, CreateFileOptions.None));
Assert.Success(fs.CreateFile("sdcard:/file".ToU8Span(), 100, CreateFileOptions.None));
}
[Fact]