Add basic filesystem accessors

This commit is contained in:
Alex Barney 2019-06-09 21:31:00 -05:00
parent f45d4166eb
commit 5a8744c6b5
8 changed files with 350 additions and 0 deletions

View 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();
}
}
}

View 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
}
}

View 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);
}
}
}
}

View file

@ -0,0 +1,7 @@
namespace LibHac.Fs.Accessors
{
public interface IAccessLogger
{
}
}

View 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;
}
}
}
}

View 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
View 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);
}
}
}

View file

@ -0,0 +1,9 @@
using System;
namespace LibHac
{
public interface ITimeSpanGenerator
{
TimeSpan GetCurrent();
}
}