mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add some RomFS and IFileStorage documentation.
This commit is contained in:
parent
f8e724fe0b
commit
29d1cd110f
11 changed files with 307 additions and 18 deletions
|
@ -79,6 +79,9 @@ namespace LibHac.IO
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies which operations are available on an <see cref="IFile"/>.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum OpenMode
|
||||
{
|
||||
|
|
|
@ -2,13 +2,38 @@
|
|||
|
||||
namespace LibHac.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an interface for enumerating the child entries of a directory.
|
||||
/// </summary>
|
||||
public interface IDirectory
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IFileSystem"/> that contains the current <see cref="IDirectory"/>.
|
||||
/// </summary>
|
||||
IFileSystem ParentFileSystem { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The full path of the current <see cref="IDirectory"/> in its <see cref="ParentFileSystem"/>.
|
||||
/// </summary>
|
||||
string FullPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies which types of entries will be enumerated when <see cref="Read"/> is called.
|
||||
/// </summary>
|
||||
OpenDirectoryMode Mode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerable collection the file system entries of the types specified by
|
||||
/// <see cref="Mode"/> that this directory contains. Does not search subdirectories.
|
||||
/// </summary>
|
||||
/// <returns>An enumerable collection of file system entries in this directory.</returns>
|
||||
IEnumerable<DirectoryEntry> Read();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of file system entries of the types specified by
|
||||
/// <see cref="Mode"/> that this directory contains. Does not search subdirectories.
|
||||
/// </summary>
|
||||
/// <returns>The number of child entries the directory contains.</returns>
|
||||
int GetEntryCount();
|
||||
}
|
||||
}
|
|
@ -2,13 +2,65 @@
|
|||
|
||||
namespace LibHac.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an interface for reading and writing a sequence of bytes.
|
||||
/// </summary>
|
||||
/// <remarks><see cref="IFile"/> is similar to <see cref="IStorage"/>, and has a few main differences:
|
||||
///
|
||||
/// - <see cref="IFile"/> allows an <see cref="OpenMode"/> to be set that controls read, write
|
||||
/// and append permissions for the file.
|
||||
///
|
||||
/// - If the <see cref="IFile"/> cannot read or write as many bytes as requested, it will read
|
||||
/// or write as many bytes as it can and return that number of bytes to the caller.
|
||||
///
|
||||
/// - If <see cref="Write"/> is called on an offset past the end of the <see cref="IFile"/>,
|
||||
/// the <see cref="OpenMode.Append"/> mode is set and the file supports expansion,
|
||||
/// the file will be expanded so that it is large enough to contain the written data.</remarks>
|
||||
public interface IFile : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The permissions mode for the current file.
|
||||
/// </summary>
|
||||
OpenMode Mode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Reads a sequence of bytes from the current <see cref="IFile"/>.
|
||||
/// </summary>
|
||||
/// <param name="destination">The buffer where the read bytes will be stored.
|
||||
/// The number of bytes read will be no larger than the length of the buffer.</param>
|
||||
/// <param name="offset">The offset in the <see cref="IFile"/> at which to begin reading.</param>
|
||||
/// <returns>The total number of bytes read into the buffer. This can be less than the
|
||||
/// size of the buffer if the IFile is too short to fulfill the request.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is invalid.</exception>
|
||||
/// <exception cref="NotSupportedException">The file's <see cref="OpenMode"/> does not allow reading.</exception>
|
||||
int Read(Span<byte> destination, long offset);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the current <see cref="IFile"/>.
|
||||
/// </summary>
|
||||
/// <param name="source">The buffer containing the bytes to be written.</param>
|
||||
/// <param name="offset">The offset in the <see cref="IStorage"/> at which to begin writing.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is negative.</exception>
|
||||
/// <exception cref="NotSupportedException">The file's <see cref="OpenMode"/> does not allow this request.</exception>
|
||||
void Write(ReadOnlySpan<byte> source, long offset);
|
||||
|
||||
/// <summary>
|
||||
/// Causes any buffered data to be written to the underlying device.
|
||||
/// </summary>
|
||||
void Flush();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of bytes in the file.
|
||||
/// </summary>
|
||||
/// <returns>The length of the file in bytes.</returns>
|
||||
long GetSize();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the size of the file in bytes.
|
||||
/// </summary>
|
||||
/// <param name="size">The desired size of the file in bytes.</param>
|
||||
/// <exception cref="NotSupportedException">If increasing the file size, The file's
|
||||
/// <see cref="OpenMode"/> does not allow this appending.</exception>
|
||||
void SetSize(long size);
|
||||
}
|
||||
}
|
|
@ -1,23 +1,116 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace LibHac.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an interface for accessing a file system. <c>/</c> is used as the path delimiter.
|
||||
/// </summary>
|
||||
public interface IFileSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates all directories and subdirectories in the specified path unless they already exist.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the directory to create.</param>
|
||||
/// <exception cref="IOException">An I/O error occurred while creating the directory.</exception>
|
||||
void CreateDirectory(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Creates or overwrites a file at the specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to create.</param>
|
||||
/// <param name="size">The initial size of the created file.</param>
|
||||
/// <param name="options">Flags to control how the file is created.
|
||||
/// Should usually be <see cref="CreateFileOptions.None"/></param>
|
||||
/// <exception cref="IOException">An I/O error occurred while creating the file.</exception>
|
||||
void CreateFile(string path, long size, CreateFileOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the directory to delete.</param>
|
||||
/// <exception cref="DirectoryNotFoundException">The specified directory does not exist.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while deleting the directory.</exception>
|
||||
void DeleteDirectory(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified file.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to delete.</param>
|
||||
/// <exception cref="FileNotFoundException">The specified file does not exist.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while deleting the file.</exception>
|
||||
void DeleteFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IDirectory"/> instance for enumerating the specified directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The directory's full path.</param>
|
||||
/// <param name="mode">Specifies which sub-entries should be enumerated.</param>
|
||||
/// <returns>An <see cref="IDirectory"/> instance for the specified directory.</returns>
|
||||
/// <exception cref="DirectoryNotFoundException">The specified directory does not exist.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while opening the directory.</exception>
|
||||
IDirectory OpenDirectory(string path, OpenDirectoryMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Opens an <see cref="IFile"/> instance for the specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to open.</param>
|
||||
/// <param name="mode">Specifies the access permissions of the created <see cref="IFile"/>.</param>
|
||||
/// <returns>An <see cref="IFile"/> instance for the specified path.</returns>
|
||||
/// <exception cref="FileNotFoundException">The specified file does not exist.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while deleting the file.</exception>
|
||||
IFile OpenFile(string path, OpenMode mode);
|
||||
|
||||
/// <summary>
|
||||
/// Renames or moves a directory to a new location.
|
||||
/// </summary>
|
||||
/// <param name="srcPath">The full path of the directory to rename.</param>
|
||||
/// <param name="dstPath">The new full path of the directory.</param>
|
||||
/// <exception cref="DirectoryNotFoundException">The specified directory does not exist.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while deleting the directory.</exception>
|
||||
void RenameDirectory(string srcPath, string dstPath);
|
||||
|
||||
/// <summary>
|
||||
/// Renames or moves a file to a new location.
|
||||
/// </summary>
|
||||
/// <param name="srcPath">The full path of the file to rename.</param>
|
||||
/// <param name="dstPath">The new full path of the file.</param>
|
||||
/// <exception cref="FileNotFoundException">The specified file does not exist.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while deleting the file.</exception>
|
||||
void RenameFile(string srcPath, string dstPath);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified directory exists.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the directory to check.</param>
|
||||
/// <returns><see langword="true"/> if the directory exists, otherwise <see langword="false"/>.</returns>
|
||||
bool DirectoryExists(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified file exists.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to check.</param>
|
||||
/// <returns><see langword="true"/> if the file exists, otherwise <see langword="false"/>.</returns>
|
||||
bool FileExists(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified path is a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path to check.</param>
|
||||
/// <returns>The <see cref="DirectoryEntryType"/> of the file.</returns>
|
||||
/// <exception cref="FileNotFoundException">The specified path does not exist.</exception>
|
||||
DirectoryEntryType GetEntryType(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Commits any changes to a transactional file system.
|
||||
/// Does nothing if called on a non-transactional file system.
|
||||
/// </summary>
|
||||
void Commit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies which types of entries are returned when enumerating an <see cref="IDirectory"/>.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum OpenDirectoryMode
|
||||
{
|
||||
|
@ -26,10 +119,16 @@ namespace LibHac.IO
|
|||
All = Directories | Files
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optional file creation flags.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum CreateFileOptions
|
||||
{
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// On a <see cref="ConcatenationFileSystem"/>, creates a concatenation file.
|
||||
/// </summary>
|
||||
CreateConcatenationFile = 1 << 0
|
||||
}
|
||||
}
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace LibHac.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an interface for reading and writing a sequence of bytes.
|
||||
/// </summary>
|
||||
public interface IStorage : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -9,14 +12,17 @@ namespace LibHac.IO
|
|||
/// </summary>
|
||||
/// <param name="destination">The buffer where the read bytes will be stored.
|
||||
/// The number of bytes read will be equal to the length of the buffer.</param>
|
||||
/// <param name="offset">The offset in the <see cref="IStorage"/> to begin reading from.</param>
|
||||
/// <param name="offset">The offset in the <see cref="IStorage"/> at which to begin reading.</param>
|
||||
/// <exception cref="ArgumentException">Invalid offset or the IStorage contains fewer bytes than requested. </exception>
|
||||
void Read(Span<byte> destination, long offset);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the current <see cref="IStorage"/>.
|
||||
/// </summary>
|
||||
/// <param name="source">The buffer containing the bytes to be written.</param>
|
||||
/// <param name="offset">The offset in the <see cref="IStorage"/> to begin writing to.</param>
|
||||
/// <param name="offset">The offset in the <see cref="IStorage"/> at which to begin writing.</param>
|
||||
/// <exception cref="ArgumentException">Invalid offset or <paramref name="source"/>
|
||||
/// is too large to be written to the IStorage. </exception>
|
||||
void Write(ReadOnlySpan<byte> source, long offset);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
|
||||
namespace LibHac.IO
|
||||
{
|
||||
|
@ -145,9 +144,6 @@ namespace LibHac.IO
|
|||
throw new FileNotFoundException(path);
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public void Commit() { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace LibHac.IO
|
|||
public void DeleteFile(string path) => throw new NotSupportedException();
|
||||
public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException();
|
||||
public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException();
|
||||
public void Commit() => throw new NotSupportedException();
|
||||
public void Commit() { }
|
||||
}
|
||||
|
||||
public enum PartitionFileSystemType
|
||||
|
|
|
@ -5,11 +5,34 @@ using System.Text;
|
|||
|
||||
namespace LibHac.IO.RomFs
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the file table used by the RomFS format.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This file table stores the structure of the file tree in a RomFS.
|
||||
/// Each file or directory entry is stored in the table using its full path as a key.
|
||||
/// Once added, a file or directory is assigned an ID that can also be used to retrieve it.
|
||||
/// Each file entry contains the size of the file and its offset in the RomFS.
|
||||
/// Each directory entry contains the IDs for its first child file and first child directory.
|
||||
///
|
||||
/// The table is represented by four byte arrays. Two of the arrays contain the hash buckets and
|
||||
/// entries for the files, and the other two for the directories.
|
||||
///
|
||||
/// Once all files have been added to the table, <see cref="TrimExcess"/> should be called
|
||||
/// to optimize the size of the table.
|
||||
/// </remarks>
|
||||
public class HierarchicalRomFileTable
|
||||
{
|
||||
private RomFsDictionary<FileRomEntry> FileTable { get; }
|
||||
private RomFsDictionary<DirectoryRomEntry> DirectoryTable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="HierarchicalRomFileTable"/> from an existing table.
|
||||
/// </summary>
|
||||
/// <param name="dirHashTable"></param>
|
||||
/// <param name="dirEntryTable"></param>
|
||||
/// <param name="fileHashTable"></param>
|
||||
/// <param name="fileEntryTable"></param>
|
||||
public HierarchicalRomFileTable(IStorage dirHashTable, IStorage dirEntryTable, IStorage fileHashTable,
|
||||
IStorage fileEntryTable)
|
||||
{
|
||||
|
@ -17,8 +40,18 @@ namespace LibHac.IO.RomFs
|
|||
DirectoryTable = new RomFsDictionary<DirectoryRomEntry>(dirHashTable, dirEntryTable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="HierarchicalRomFileTable"/> that has the default initial capacity.
|
||||
/// </summary>
|
||||
public HierarchicalRomFileTable() : this(0, 0) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="HierarchicalRomFileTable"/> that has the specified initial capacity.
|
||||
/// </summary>
|
||||
/// <param name="directoryCapacity">The initial number of directories that the
|
||||
/// <see cref="HierarchicalRomFileTable"/> can contain.</param>
|
||||
/// <param name="fileCapacity">The initial number of files that the
|
||||
/// <see cref="HierarchicalRomFileTable"/> can contain.</param>
|
||||
public HierarchicalRomFileTable(int directoryCapacity, int fileCapacity)
|
||||
{
|
||||
FileTable = new RomFsDictionary<FileRomEntry>(fileCapacity);
|
||||
|
@ -73,6 +106,13 @@ namespace LibHac.IO.RomFs
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a directory for enumeration.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the directory to open.</param>
|
||||
/// <param name="position">The initial position of the directory enumerator.</param>
|
||||
/// <returns><see langword="true"/> if the table contains a directory with the specified path;
|
||||
/// otherwise, <see langword="false"/>.</returns>
|
||||
public bool TryOpenDirectory(string path, out FindPosition position)
|
||||
{
|
||||
FindDirectoryRecursive(GetUtf8Bytes(path), out RomEntryKey key);
|
||||
|
@ -87,6 +127,13 @@ namespace LibHac.IO.RomFs
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a directory for enumeration.
|
||||
/// </summary>
|
||||
/// <param name="directoryId">The ID of the directory to open.</param>
|
||||
/// <param name="position">When this method returns, contains the initial position of the directory enumerator.</param>
|
||||
/// <returns><see langword="true"/> if the table contains a directory with the specified path;
|
||||
/// otherwise, <see langword="false"/>.</returns>
|
||||
public bool TryOpenDirectory(int directoryId, out FindPosition position)
|
||||
{
|
||||
if (DirectoryTable.TryGetValue(directoryId, out RomKeyValuePair<DirectoryRomEntry> keyValuePair))
|
||||
|
@ -99,6 +146,15 @@ namespace LibHac.IO.RomFs
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next file in a directory and updates the enumerator's position.
|
||||
/// </summary>
|
||||
/// <param name="position">The current position of the directory enumerator.
|
||||
/// This position will be updated when the method returns.</param>
|
||||
/// <param name="info">When this method returns, contains the file's metadata.</param>
|
||||
/// <param name="name">When this method returns, contains the file's name (Not the full path).</param>
|
||||
/// <returns><see langword="true"/> if the next file was successfully returned.
|
||||
/// <see langword="false"/> if there are no more files to enumerate.</returns>
|
||||
public bool FindNextFile(ref FindPosition position, out RomFileInfo info, out string name)
|
||||
{
|
||||
if (position.NextFile == -1)
|
||||
|
@ -117,6 +173,14 @@ namespace LibHac.IO.RomFs
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next child directory in a directory and updates the enumerator's position.
|
||||
/// </summary>
|
||||
/// <param name="position">The current position of the directory enumerator.
|
||||
/// This position will be updated when the method returns.</param>
|
||||
/// <param name="name">When this method returns, contains the directory's name (Not the full path).</param>
|
||||
/// <returns><see langword="true"/> if the next directory was successfully returned.
|
||||
/// <see langword="false"/> if there are no more directories to enumerate.</returns>
|
||||
public bool FindNextDirectory(ref FindPosition position, out string name)
|
||||
{
|
||||
if (position.NextDirectory == -1)
|
||||
|
@ -132,7 +196,13 @@ namespace LibHac.IO.RomFs
|
|||
return true;
|
||||
}
|
||||
|
||||
public void CreateFile(string path, ref RomFileInfo fileInfo)
|
||||
/// <summary>
|
||||
/// Adds a file to the file table. If the file already exists
|
||||
/// its <see cref="RomFileInfo"/> will be updated.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to be added.</param>
|
||||
/// <param name="fileInfo">The file information to be stored.</param>
|
||||
public void AddFile(string path, ref RomFileInfo fileInfo)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
ReadOnlySpan<byte> pathBytes = GetUtf8Bytes(path);
|
||||
|
@ -140,13 +210,25 @@ namespace LibHac.IO.RomFs
|
|||
CreateFileRecursiveInternal(pathBytes, ref fileInfo);
|
||||
}
|
||||
|
||||
public void CreateDirectory(string path)
|
||||
/// <summary>
|
||||
/// Adds a directory to the file table. If the directory already exists,
|
||||
/// no action is performed.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the directory to be added.</param>
|
||||
public void AddDirectory(string path)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
CreateDirectoryRecursive(GetUtf8Bytes(path));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the capacity of this dictionary to what it would be if
|
||||
/// it had been originally initialized with all its entries.
|
||||
///
|
||||
/// This method can be used to minimize the memory overhead
|
||||
/// once it is known that no new elements will be added.
|
||||
/// </summary>
|
||||
public void TrimExcess()
|
||||
{
|
||||
DirectoryTable.TrimExcess();
|
||||
|
@ -263,9 +345,9 @@ namespace LibHac.IO.RomFs
|
|||
}
|
||||
|
||||
{
|
||||
ref FileRomEntry entry = ref FileTable.AddOrGet(ref key, out int offset, out _, out _);
|
||||
entry.NextSibling = -1;
|
||||
ref FileRomEntry entry = ref FileTable.AddOrGet(ref key, out int offset, out bool alreadyExists, out _);
|
||||
entry.Info = fileInfo;
|
||||
if (alreadyExists) entry.NextSibling = -1;
|
||||
|
||||
ref DirectoryRomEntry parent = ref DirectoryTable.GetValueReference(prevOffset);
|
||||
|
||||
|
|
|
@ -5,6 +5,12 @@ using System.Linq;
|
|||
|
||||
namespace LibHac.IO.RomFs
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds a RomFS from a collection of files.
|
||||
/// </summary>
|
||||
/// <remarks>A <see cref="RomFsBuilder"/> produces a view of a RomFS archive.
|
||||
/// When doing so, it will create an <see cref="IStorage"/> instance that will
|
||||
/// provide the RomFS data when read. Random seek is supported.</remarks>
|
||||
public class RomFsBuilder
|
||||
{
|
||||
private const int FileAlignment = 0x10;
|
||||
|
@ -15,8 +21,15 @@ namespace LibHac.IO.RomFs
|
|||
private HierarchicalRomFileTable FileTable { get; } = new HierarchicalRomFileTable();
|
||||
private long CurrentOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new, empty <see cref="RomFsBuilder"/>
|
||||
/// </summary>
|
||||
public RomFsBuilder() { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="RomFsBuilder"/> and populates it with all
|
||||
/// the files in the specified <see cref="IFileSystem"/>.
|
||||
/// </summary>
|
||||
public RomFsBuilder(IFileSystem input)
|
||||
{
|
||||
foreach (DirectoryEntry file in input.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File)
|
||||
|
@ -26,6 +39,11 @@ namespace LibHac.IO.RomFs
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a file to the RomFS.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path in the RomFS</param>
|
||||
/// <param name="file">An <see cref="IFile"/> of the file data to add.</param>
|
||||
public void AddFile(string path, IFile file)
|
||||
{
|
||||
var fileInfo = new RomFileInfo();
|
||||
|
@ -43,9 +61,15 @@ namespace LibHac.IO.RomFs
|
|||
var padding = new NullStorage(CurrentOffset - newOffset);
|
||||
Sources.Add(padding);
|
||||
|
||||
FileTable.CreateFile(path, ref fileInfo);
|
||||
FileTable.AddFile(path, ref fileInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a view of a RomFS containing all the currently added files.
|
||||
/// Additional files may be added and a new view produced without
|
||||
/// invalidating previously built RomFS views.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IStorage Build()
|
||||
{
|
||||
FileTable.TrimExcess();
|
||||
|
|
|
@ -46,10 +46,15 @@ namespace LibHac.IO.RomFs
|
|||
public long Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the current position when enumerating a directory's contents.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FindPosition
|
||||
{
|
||||
/// <summary>The ID of the next directory to be enumerated.</summary>
|
||||
public int NextDirectory;
|
||||
/// <summary>The ID of the next file to be enumerated.</summary>
|
||||
public int NextFile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,10 +34,7 @@ namespace LibHac.IO.RomFs
|
|||
throw new FileNotFoundException(path);
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public void Commit() { }
|
||||
|
||||
public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue