mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add basic filesystem accessors
This commit is contained in:
parent
f45d4166eb
commit
5a8744c6b5
8 changed files with 350 additions and 0 deletions
27
src/LibHac/Fs/Accessors/DirectoryAccessor.cs
Normal file
27
src/LibHac/Fs/Accessors/DirectoryAccessor.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace LibHac.Fs.Accessors
|
||||||
|
{
|
||||||
|
public class DirectoryAccessor
|
||||||
|
{
|
||||||
|
private IDirectory Directory { get; }
|
||||||
|
|
||||||
|
public FileSystemAccessor Parent { get; }
|
||||||
|
|
||||||
|
public DirectoryAccessor(IDirectory baseDirectory, FileSystemAccessor parent)
|
||||||
|
{
|
||||||
|
Directory = baseDirectory;
|
||||||
|
Parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<DirectoryEntry> Read()
|
||||||
|
{
|
||||||
|
return Directory.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetEntryCount()
|
||||||
|
{
|
||||||
|
return Directory.GetEntryCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
src/LibHac/Fs/Accessors/FileAccessor.cs
Normal file
63
src/LibHac/Fs/Accessors/FileAccessor.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LibHac.Fs.Accessors
|
||||||
|
{
|
||||||
|
public class FileAccessor
|
||||||
|
{
|
||||||
|
private IFile File { get; }
|
||||||
|
|
||||||
|
public FileSystemAccessor Parent { get; }
|
||||||
|
public WriteState WriteState { get; private set; }
|
||||||
|
public OpenMode OpenMode { get; }
|
||||||
|
|
||||||
|
public FileAccessor(IFile baseFile, FileSystemAccessor parent, OpenMode mode)
|
||||||
|
{
|
||||||
|
File = baseFile;
|
||||||
|
Parent = parent;
|
||||||
|
OpenMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Read(Span<byte> destination, long offset, ReadOption options)
|
||||||
|
{
|
||||||
|
return File.Read(destination, offset, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
|
||||||
|
{
|
||||||
|
if (source.Length == 0)
|
||||||
|
{
|
||||||
|
WriteState = (WriteState)(~options & WriteOption.Flush);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Write(source, offset, options);
|
||||||
|
|
||||||
|
WriteState = (WriteState)(~options & WriteOption.Flush);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Flush()
|
||||||
|
{
|
||||||
|
File.Flush();
|
||||||
|
|
||||||
|
WriteState = WriteState.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetSize()
|
||||||
|
{
|
||||||
|
return File.GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSize(long size)
|
||||||
|
{
|
||||||
|
File.SetSize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum WriteState
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Unflushed,
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
}
|
155
src/LibHac/Fs/Accessors/FileSystemAccessor.cs
Normal file
155
src/LibHac/Fs/Accessors/FileSystemAccessor.cs
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using static LibHac.Fs.ResultsFs;
|
||||||
|
|
||||||
|
namespace LibHac.Fs.Accessors
|
||||||
|
{
|
||||||
|
public class FileSystemAccessor
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
private IFileSystem FileSystem { get; }
|
||||||
|
|
||||||
|
private HashSet<FileAccessor> OpenFiles { get; } = new HashSet<FileAccessor>();
|
||||||
|
private HashSet<DirectoryAccessor> OpenDirectories { get; } = new HashSet<DirectoryAccessor>();
|
||||||
|
|
||||||
|
private readonly object _locker = new object();
|
||||||
|
|
||||||
|
public FileSystemAccessor(string name, IFileSystem baseFileSystem)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
FileSystem = baseFileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateDirectory(string path)
|
||||||
|
{
|
||||||
|
FileSystem.CreateDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateFile(string path, long size, CreateFileOptions options)
|
||||||
|
{
|
||||||
|
FileSystem.CreateFile(path, size, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteDirectory(string path)
|
||||||
|
{
|
||||||
|
FileSystem.DeleteDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteDirectoryRecursively(string path)
|
||||||
|
{
|
||||||
|
FileSystem.DeleteDirectoryRecursively(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CleanDirectoryRecursively(string path)
|
||||||
|
{
|
||||||
|
FileSystem.CleanDirectoryRecursively(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteFile(string path)
|
||||||
|
{
|
||||||
|
FileSystem.DeleteFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectoryAccessor OpenDirectory(string path, OpenDirectoryMode mode)
|
||||||
|
{
|
||||||
|
IDirectory dir = FileSystem.OpenDirectory(path, mode);
|
||||||
|
|
||||||
|
var accessor = new DirectoryAccessor(dir, this);
|
||||||
|
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
OpenDirectories.Add(accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileAccessor OpenFile(string path, OpenMode mode)
|
||||||
|
{
|
||||||
|
IFile file = FileSystem.OpenFile(path, mode);
|
||||||
|
|
||||||
|
var accessor = new FileAccessor(file, this, mode);
|
||||||
|
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
OpenFiles.Add(accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenameDirectory(string srcPath, string dstPath)
|
||||||
|
{
|
||||||
|
FileSystem.RenameDirectory(srcPath, dstPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenameFile(string srcPath, string dstPath)
|
||||||
|
{
|
||||||
|
FileSystem.RenameFile(srcPath, dstPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DirectoryExists(string path)
|
||||||
|
{
|
||||||
|
FileSystem.DirectoryExists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FileExists(string path)
|
||||||
|
{
|
||||||
|
FileSystem.FileExists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectoryEntryType GetEntryType(string path)
|
||||||
|
{
|
||||||
|
return FileSystem.GetEntryType(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetFreeSpaceSize(string path)
|
||||||
|
{
|
||||||
|
return FileSystem.GetFreeSpaceSize(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetTotalSpaceSize(string path)
|
||||||
|
{
|
||||||
|
return FileSystem.GetTotalSpaceSize(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileTimeStampRaw GetFileTimeStampRaw(string path)
|
||||||
|
{
|
||||||
|
return FileSystem.GetFileTimeStampRaw(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Commit()
|
||||||
|
{
|
||||||
|
if (OpenFiles.Any(x => (x.OpenMode & OpenMode.Write) != 0))
|
||||||
|
{
|
||||||
|
ThrowHelper.ThrowResult(ResultFsWritableFileOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystem.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, string path, QueryId queryId)
|
||||||
|
{
|
||||||
|
FileSystem.QueryEntry(outBuffer, inBuffer, path, queryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void NotifyCloseFile(FileAccessor file)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
OpenFiles.Remove(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void NotifyCloseDirectory(DirectoryAccessor directory)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
OpenDirectories.Remove(directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/LibHac/Fs/Accessors/IAccessLogger.cs
Normal file
7
src/LibHac/Fs/Accessors/IAccessLogger.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace LibHac.Fs.Accessors
|
||||||
|
{
|
||||||
|
public interface IAccessLogger
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
57
src/LibHac/Fs/Accessors/MountTable.cs
Normal file
57
src/LibHac/Fs/Accessors/MountTable.cs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using static LibHac.Results;
|
||||||
|
using static LibHac.Fs.ResultsFs;
|
||||||
|
|
||||||
|
namespace LibHac.Fs.Accessors
|
||||||
|
{
|
||||||
|
public class MountTable
|
||||||
|
{
|
||||||
|
private Dictionary<string, FileSystemAccessor> Table { get; } = new Dictionary<string, FileSystemAccessor>();
|
||||||
|
|
||||||
|
private readonly object _locker = new object();
|
||||||
|
|
||||||
|
public Result Mount(FileSystemAccessor fileSystem)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
string mountName = fileSystem.Name;
|
||||||
|
|
||||||
|
if (Table.ContainsKey(mountName))
|
||||||
|
{
|
||||||
|
return ResultFsMountNameAlreadyExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
Table.Add(mountName, fileSystem);
|
||||||
|
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result Find(string name, out FileSystemAccessor fileSystem)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
if (!Table.TryGetValue(name, out fileSystem))
|
||||||
|
{
|
||||||
|
return ResultFsMountNameNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result Unmount(string name)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
if (!Table.Remove(name))
|
||||||
|
{
|
||||||
|
return ResultFsMountNameNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/LibHac/Fs/FileSystemManager.cs
Normal file
16
src/LibHac/Fs/FileSystemManager.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using LibHac.Fs.Accessors;
|
||||||
|
|
||||||
|
namespace LibHac.Fs
|
||||||
|
{
|
||||||
|
public class FileSystemManager
|
||||||
|
{
|
||||||
|
internal Horizon Os { get; }
|
||||||
|
|
||||||
|
internal MountTable MountTable { get; } = new MountTable();
|
||||||
|
|
||||||
|
public FileSystemManager(Horizon os)
|
||||||
|
{
|
||||||
|
Os = os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/LibHac/Horizon.cs
Normal file
16
src/LibHac/Horizon.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using LibHac.Fs;
|
||||||
|
|
||||||
|
namespace LibHac
|
||||||
|
{
|
||||||
|
public class Horizon
|
||||||
|
{
|
||||||
|
internal ITimeSpanGenerator Time { get; }
|
||||||
|
|
||||||
|
public FileSystemManager Fs { get; }
|
||||||
|
|
||||||
|
public Horizon()
|
||||||
|
{
|
||||||
|
Fs = new FileSystemManager(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
src/LibHac/ITimeSpanGenerator.cs
Normal file
9
src/LibHac/ITimeSpanGenerator.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LibHac
|
||||||
|
{
|
||||||
|
public interface ITimeSpanGenerator
|
||||||
|
{
|
||||||
|
TimeSpan GetCurrent();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue