Skip to content

Commit

Permalink
Add XML API documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Sep 8, 2024
1 parent 88e1de1 commit 280cde5
Show file tree
Hide file tree
Showing 19 changed files with 590 additions and 145 deletions.
3 changes: 2 additions & 1 deletion src/XenoAtom.UnixTools.Tests/CpioTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void TestWithFileSystem()
var fileStream = new MemoryStream(File.ReadAllBytes(@"cpio_archive_test.cpio"));
var fileStreamOut = new MemoryStream();

var fs = new UnixMemoryFileSystem();
var fs = new UnixInMemoryFileSystem();
var entries = new List<CpioEntry>();

// Use a block to dispose the reader/writer
Expand Down Expand Up @@ -121,6 +121,7 @@ public void TestWithFileSystem()
Assert.AreEqual(entry.HardLinkCount, entryOut.HardLinkCount, "Invalid hard link count");
Assert.AreEqual(entry.Device, entryOut.Device, "Invalid device");
Assert.AreEqual(entry.ModificationTime, entryOut.ModificationTime, "Invalid modification time");
Assert.AreEqual(entry.Checksum, entryOut.Checksum, "Invalid checksum");

Assert.AreEqual(entry.LinkName, entryOut.LinkName, "Invalid link name");

Expand Down
8 changes: 4 additions & 4 deletions src/XenoAtom.UnixTools.Tests/TestFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class TestFileSystem
[TestMethod]
public void TestSimple()
{
var fs = new UnixMemoryFileSystem();
var fs = new UnixInMemoryFileSystem();
var root = fs.RootDirectory;
Assert.IsTrue(root.IsRoot);
Assert.AreEqual("/", root.FullPath);
Expand Down Expand Up @@ -222,10 +222,10 @@ public void TestRemoveHardLinkFile()
Assert.AreEqual(1U, file3.HardLinkCount);
Assert.IsTrue(file3.IsAttached);
}
private static UnixMemoryFileSystem CreateSimpleFileSystem()

private static UnixInMemoryFileSystem CreateSimpleFileSystem()
{
var fs = new UnixMemoryFileSystem();
var fs = new UnixInMemoryFileSystem();
var root = fs.RootDirectory;
var dir1 = root.CreateDirectory("dir1");
var file1 = dir1.CreateFile("file1", "HelloWorld");
Expand Down
3 changes: 3 additions & 0 deletions src/XenoAtom.UnixTools/CpioEntryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace XenoAtom.UnixTools;

/// <summary>
/// Extensions for <see cref="CpioEntry"/>.
/// </summary>
public static class CpioEntryExtensions
{
/// <summary>
Expand Down
5 changes: 0 additions & 5 deletions src/XenoAtom.UnixTools/CpioReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ public CpioReader(Stream stream, bool leaveOpen = false)
_positionInSuperStream = stream.CanSeek ? stream.Position : 0;
}

/// <summary>
/// Gets the underlying stream.
/// </summary>
public Stream Stream => _stream;

/// <summary>
/// Tries to get the next entry from the CPIO archive.
/// </summary>
Expand Down
7 changes: 1 addition & 6 deletions src/XenoAtom.UnixTools/CpioWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace XenoAtom.UnixTools;

/// <summary>
/// Provides a raw writer for CPIO archives. For a higher level API, use <see cref="CpioFileSystemBuilder"/>.
/// Provides a raw writer for CPIO archives. For a higher level API, use <see cref="UnixInMemoryFileSystem"/> and <see cref="UnixMemoryFileSystemExtensions.WriteTo(XenoAtom.UnixTools.UnixInMemoryFileSystem,XenoAtom.UnixTools.CpioWriter)"/>.
/// </summary>
public sealed unsafe class CpioWriter : IDisposable
{
Expand Down Expand Up @@ -39,11 +39,6 @@ public CpioWriter(Stream stream, bool leaveOpen = false)
_positionInSuperStream = stream.CanSeek ? stream.Position : 0;
}

/// <summary>
/// Gets the underlying stream.
/// </summary>
public Stream Stream => _stream;

/// <summary>
/// Adds a new entry to the CPIO archive.
/// </summary>
Expand Down
3 changes: 3 additions & 0 deletions src/XenoAtom.UnixTools/UnixDeviceFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace XenoAtom.UnixTools;

/// <summary>
/// A Unix device file.
/// </summary>
public sealed class UnixDeviceFile : UnixFileSystemEntry
{
internal UnixDeviceFile(string name, UnixInode node) : base(name, node)
Expand Down
123 changes: 120 additions & 3 deletions src/XenoAtom.UnixTools/UnixDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,40 @@

namespace XenoAtom.UnixTools;

/// <summary>
/// A Unix directory.
/// </summary>
public sealed class UnixDirectory : UnixFileSystemEntry
{
private const int MaximumPathDepth = 2048;

/// <summary>
/// The default mode used when creating a directory.
/// </summary>
public const UnixFileMode DefaultMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | UnixFileMode.GroupRead | UnixFileMode.GroupExecute | UnixFileMode.OtherRead | UnixFileMode.OtherExecute;

internal UnixDirectory(string name, UnixInode node) : base(name, node)
{
}


/// <summary>
/// Gets a boolean indicating whether this directory is the root directory.
/// </summary>
public bool IsRoot => Parent == null && Name.Length == 0;

/// <summary>
/// Gets the entries of this directory.
/// </summary>
public SortedDictionary<string, UnixFileSystemEntry>.ValueCollection Entries => InternalEntries.Values;

internal SortedDictionary<string, UnixFileSystemEntry> InternalEntries => Inode.GetDictionaryContent();


/// <summary>
/// Creates a file in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <param name="createIntermediateDirectories">A boolean indicating whether intermediate directories should be created.</param>
/// <returns>The created entry.</returns>
public UnixFile CreateFile(string path, bool createIntermediateDirectories = false)
{
var (dir, name) = ResolveEntryForCreate(path, createIntermediateDirectories);
Expand All @@ -35,6 +53,13 @@ public UnixFile CreateFile(string path, bool createIntermediateDirectories = fal
return file;
}

/// <summary>
/// Creates a file in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <param name="content">The content of the file.</param>
/// <param name="createIntermediateDirectories">A boolean indicating whether intermediate directories should be created.</param>
/// <returns>The created entry.</returns>
public UnixFile CreateFile(string path, UnixFileContent content, bool createIntermediateDirectories = false)
{
var (dir, name) = ResolveEntryForCreate(path, createIntermediateDirectories);
Expand All @@ -44,6 +69,12 @@ public UnixFile CreateFile(string path, UnixFileContent content, bool createInte
return file;
}

/// <summary>
/// Creates a directory in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <param name="createIntermediateDirectories">A boolean indicating whether intermediate directories should be created.</param>
/// <returns>The created entry.</returns>
public UnixDirectory CreateDirectory(string path, bool createIntermediateDirectories = false)
{
var (dir, name) = ResolveEntryForCreate(path, createIntermediateDirectories);
Expand All @@ -53,6 +84,15 @@ public UnixDirectory CreateDirectory(string path, bool createIntermediateDirecto
return directory;
}

/// <summary>
/// Creates a device file in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <param name="kind">The kind of device file. The value must be <see cref="UnixFileKind.CharacterSpecialDevice"/> or <see cref="UnixFileKind.BlockSpecialDevice"/></param>
/// <param name="id">The device id.</param>
/// <param name="createIntermediateDirectories">A boolean indicating whether intermediate directories should be created.</param>
/// <returns>The created entry.</returns>
/// <exception cref="ArgumentException">If <paramref name="kind"/> is not <see cref="UnixFileKind.CharacterSpecialDevice"/> or <see cref="UnixFileKind.BlockSpecialDevice"/>.</exception>
public UnixDeviceFile CreateDevice(string path, UnixFileKind kind, DeviceId id, bool createIntermediateDirectories = false)
{
if (kind != UnixFileKind.CharacterSpecialDevice && kind != UnixFileKind.BlockSpecialDevice)
Expand All @@ -69,16 +109,33 @@ public UnixDeviceFile CreateDevice(string path, UnixFileKind kind, DeviceId id,
return device;
}

/// <summary>
/// Creates a symbolic link in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <param name="target">The target of the symbolic link.</param>
/// <param name="createIntermediateDirectories">A boolean indicating whether intermediate directories should be created.</param>
/// <returns>The created entry.</returns>
public UnixSymbolicLink CreateSymbolicLink(string path, string target, bool createIntermediateDirectories = false)
{
var (dir, name) = ResolveEntryForCreate(path, createIntermediateDirectories);
// A symbolic link doesn't check if the target exists
UnixPath.Validate(target, nameof(target));
target = UnixPath.Normalize(target); // Make sure that the link is noramlized
var node = CreateNode(UnixFileKind.SymbolicLink, target);
var link = new UnixSymbolicLink(name!, node);
dir.AddEntry(link);
return link;
}

/// <summary>
/// Creates a hard link in this directory.
/// </summary>
/// <typeparam name="TEntry"></typeparam>
/// <param name="path">A path relative to this directory.</param>
/// <param name="target">The target of this hardlink.</param>
/// <param name="createIntermediateDirectories">A boolean indicating whether intermediate directories should be created.</param>
/// <returns>The created entry.</returns>
public TEntry CreateHardLink<TEntry>(string path, TEntry target, bool createIntermediateDirectories = false) where TEntry: UnixFileSystemEntry
{
var (dir, name) = ResolveEntryForCreate(path, createIntermediateDirectories);
Expand All @@ -87,11 +144,22 @@ public TEntry CreateHardLink<TEntry>(string path, TEntry target, bool createInte
return link;
}

/// <summary>
/// Checks if an entry exists in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <returns>A boolean indicating whether the entry exists.</returns>
public bool ContainsEntry(string path)
{
return TryGetEntry(path, out _);
}

/// <summary>
/// Tries to get an entry in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <param name="entry">The entry if found.</param>
/// <returns>A boolean indicating whether the entry was found.</returns>
public bool TryGetEntry(string path, [NotNullWhen(true)] out UnixFileSystemEntry? entry)
{
var dir = this;
Expand All @@ -106,8 +174,19 @@ public bool TryGetEntry(string path, [NotNullWhen(true)] out UnixFileSystemEntry
return dir.InternalEntries.TryGetValue(name!, out entry);
}

/// <summary>
/// Gets an entry in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <returns>The entry found.</returns>
public UnixFileSystemEntry this[string path] => GetEntry(path);

/// <summary>
/// Gets an entry in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <returns>The entry found.</returns>
/// <exception cref="ArgumentException">If the entry does not exist.</exception>
public UnixFileSystemEntry GetEntry(string path)
{
if (!TryGetEntry(path, out var entry))
Expand All @@ -117,6 +196,17 @@ public UnixFileSystemEntry GetEntry(string path)
return entry;
}

/// <summary>
/// Copies an entry to a destination path.
/// </summary>
/// <param name="sourcePath">The source path relative to this directory.</param>
/// <param name="destinationPath">The destination path relative to this directory.</param>
/// <param name="mode">The copy mode.</param>
/// <param name="overwrite">A boolean indicating whether to overwrite the destination entry if it already exists.</param>
/// <exception cref="ArgumentException">If the source path does not exist.</exception>
/// <remarks>
/// If the destination path is a directory, the source entry is copied into it.
/// </remarks>
public void CopyEntry(string sourcePath, string destinationPath, UnixCopyMode mode = UnixCopyMode.Single, bool overwrite = false)
{
VerifyAttached();
Expand Down Expand Up @@ -218,6 +308,17 @@ public void CopyEntry(string sourcePath, string destinationPath, UnixCopyMode mo
}
}

/// <summary>
/// Moves an entry to a destination path.
/// </summary>
/// <param name="sourcePath">The source path relative to this directory.</param>
/// <param name="destinationPath">The destination path relative to this directory.</param>
/// <param name="createIntermediateDirectories">A boolean indicating whether intermediate directories should be created.</param>
/// <param name="overwrite">A boolean indicating whether to overwrite the destination entry if it already exists.</param>
/// <exception cref="ArgumentException">If the source path does not exist.</exception>
/// <remarks>
/// If the destination path is a directory, the source entry is moved into it.
/// </remarks>
public void MoveEntry(string sourcePath, string destinationPath, bool createIntermediateDirectories = false, bool overwrite = false)
{
VerifyAttached();
Expand Down Expand Up @@ -271,6 +372,11 @@ public void MoveEntry(string sourcePath, string destinationPath, bool createInte
sourceEntry.SetParent(destinationDirectory, destinationName!);
}

/// <summary>
/// Deletes an entry in this directory.
/// </summary>
/// <param name="path">A path relative to this directory.</param>
/// <exception cref="InvalidOperationException">If the entry is the root directory.</exception>
public void DeleteEntry(string path)
{
var entry = GetEntry(path);
Expand All @@ -281,6 +387,11 @@ public void DeleteEntry(string path)
entry.SetParent(null);
}

/// <summary>
/// Enumerates the file system entries in this directory.
/// </summary>
/// <param name="searchOption">The search option.</param>
/// <returns>An enumeration of file system entries.</returns>
public IEnumerable<UnixFileSystemEntry> EnumerateFileSystemEntries(SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
if (searchOption == SearchOption.TopDirectoryOnly)
Expand All @@ -306,6 +417,12 @@ public IEnumerable<UnixFileSystemEntry> EnumerateFileSystemEntries(SearchOption
}
}

/// <summary>
/// Enumerates the file system entries in this directory.
/// </summary>
/// <param name="searchPattern">The search pattern.</param>
/// <param name="searchOption">The search option.</param>
/// <returns>An enumeration of file system entries.</returns>
public IEnumerable<UnixFileSystemEntry> EnumerateFileSystemEntries(string searchPattern, SearchOption searchOption = SearchOption.TopDirectoryOnly)
{
// Make a copy (to allow adding/removing entries while iterating)
Expand Down Expand Up @@ -540,7 +657,7 @@ private void ThrowEntryAlreadyExists(UnixDirectory directory, string name)
throw new ArgumentException($"An entry with the name `{name}` already exists in the directory `{directory.FullPath}`");
}

internal static UnixDirectory CreateRoot(UnixMemoryFileSystem fs)
internal static UnixDirectory CreateRoot(UnixInMemoryFileSystem fs)
{
var node = new UnixInode(0, UnixFileKind.Directory, new SortedDictionary<string, UnixFileSystemEntry>(StringComparer.Ordinal))
{
Expand Down
6 changes: 6 additions & 0 deletions src/XenoAtom.UnixTools/UnixFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@

namespace XenoAtom.UnixTools;

/// <summary>
/// A Unix file.
/// </summary>
public sealed class UnixFile : UnixFileSystemEntry
{
/// <summary>
/// The default mode when creating a new file.
/// </summary>
public const UnixFileMode DefaultMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.OtherRead;

internal UnixFile(string name, UnixInode node) : base(name, node)
Expand Down
Loading

0 comments on commit 280cde5

Please sign in to comment.