diff --git a/readme.md b/readme.md index 9525def..4b9b920 100644 --- a/readme.md +++ b/readme.md @@ -2,15 +2,42 @@ -This is a default project description. +This project provides a set of Unix tools for .NET 8.0+. -## ✨ Features - -- TODO +> **Note**: This project is still in early development and the API is subject to change. -## 📖 User Guide +## ✨ Features -For more details on how to use XenoAtom.UnixTools, please visit the [user guide](https://github.com/xoofx/XenoAtom.UnixTools/blob/main/doc/readme.md). +- **CPIO Archive**: Read and write CPIO archives (Only the newc format is supported) +- **UnixInMemoryFileSystem**: A simple in-memory file system to manipulate files and directories + - This in memory filesystem can be used to easily manipulate in and out CPIO archives +- .NET 8.0+ compatible and NativeAOT ready + +## 📖 Usage + +Reading a CPIO archive: + +```csharp +var cpioReader = new CpioReader(File.OpenRead("archive.cpio")); +while (cpioReader.TryGetNextEntry(out var entry)) +{ + Console.WriteLine($"Entry: {entry.Name} {entry.FileType} ({entry.Mode})"); +}) +``` + +Writing a CPIO archive with a `UnixInMemoryFileSystem`: + +```csharp +var stream = new MemoryStream(); +var fs = new UnixInMemoryFileSystem(); +fs.CreateDirectory("/dir1"); +fs.CreateDirectory("/dir1/dir2"); +fs.CreateFile("/dir1/file1.txt", "Hello World"); +{ + using var writer = new CpioWriter(File.Create("archive.cpio")); + fs.WriteTo(writer); +} +``` ## 🪪 License diff --git a/src/XenoAtom.UnixTools.Tests/CpioTests.cs b/src/XenoAtom.UnixTools.Tests/CpioTests.cs index 14ac586..7e5655d 100644 --- a/src/XenoAtom.UnixTools.Tests/CpioTests.cs +++ b/src/XenoAtom.UnixTools.Tests/CpioTests.cs @@ -2,11 +2,93 @@ // Licensed under the BSD-Clause 2 license. // See license.txt file in the project root for full license information. +using System.Text; + namespace XenoAtom.UnixTools.Tests; [TestClass] public class CpioTests { + [TestMethod] + public void TestWriterWithFileSystem() + { + var stream = new MemoryStream(); + var fs = new UnixInMemoryFileSystem(); + fs.CreateDirectory("/dir1"); + fs.CreateDirectory("/dir1/dir2"); + fs.CreateFile("/dir1/file1.txt", "Hello World"); + { + //using var writer = new CpioWriter(File.Create("archive.cpio")); + using var writer = new CpioWriter(stream, true); + fs.WriteTo(writer); + } + + stream.Position = 0; + var reader = new CpioReader(stream, true); + var fsOut = new UnixInMemoryFileSystem(); + fsOut.ReadFrom(reader); + + CollectionAssert.AreEqual(fs.RootDirectory.EnumerateFileSystemEntries(SearchOption.AllDirectories).Select(x => x.FullPath).ToList(), fsOut.RootDirectory.EnumerateFileSystemEntries(SearchOption.AllDirectories).Select(x => x.FullPath).ToList()); + } + + [TestMethod] + public void TestManualArchiveReadWrite() + { + var entry = new CpioEntry + { + Name = "test.txt", + InodeNumber = 0, + FileType = CpioFileType.RegularFile, + Mode = UnixFileMode.UserRead | UnixFileMode.UserWrite, + Uid = 0, + Gid = 0, + Length = 11, + HardLinkCount = 1, + Device = new DeviceId(1, 3), + ModificationTime = new DateTimeOffset(2010, 1, 1, 0, 0, 0, default), + Checksum = 0, + DataStream = new MemoryStream(Encoding.UTF8.GetBytes("Hello World")) + }; + + var fileStream = new MemoryStream(); + using (var writer = new CpioWriter(fileStream, true)) + { + writer.AddEntry(entry); + } + + fileStream.Position = 0; + using (var reader = new CpioReader(fileStream)) + { + Assert.IsTrue(reader.TryGetNextEntry(out var entryOut)); + Assert.AreEqual(entry.Name, entryOut.Name); + Assert.AreEqual(entry.InodeNumber, entryOut.InodeNumber); + Assert.AreEqual(entry.FileType, entryOut.FileType); + Assert.AreEqual(entry.Mode, entryOut.Mode); + Assert.AreEqual(entry.Uid, entryOut.Uid); + Assert.AreEqual(entry.Gid, entryOut.Gid); + Assert.AreEqual(entry.Length, entryOut.Length); + Assert.AreEqual(entry.HardLinkCount, entryOut.HardLinkCount); + Assert.AreEqual(entry.Device, entryOut.Device); + Assert.AreEqual(entry.ModificationTime, entryOut.ModificationTime); + Assert.AreEqual(entry.Checksum, entryOut.Checksum); + + Assert.AreEqual(entry.DataStream.Length, entryOut.DataStream.Length); + + var contentIn = new MemoryStream(); + var contentOut = new MemoryStream(); + entry.DataStream.Position = 0; + entry.DataStream.CopyTo(contentIn); + entryOut.DataStream.Position = 0; + entryOut.DataStream.CopyTo(contentOut); + + Assert.AreEqual(contentIn.Length, contentOut.Length); + for (int i = 0; i < contentIn.Length; i++) + { + Assert.AreEqual(contentIn.GetBuffer()[i], contentOut.GetBuffer()[i]); + } + } + } + /// /// Test reading an existing archive and writing it as-is. /// diff --git a/src/XenoAtom.UnixTools/XenoAtom.UnixTools.csproj b/src/XenoAtom.UnixTools/XenoAtom.UnixTools.csproj index 333bd65..f3761d0 100644 --- a/src/XenoAtom.UnixTools/XenoAtom.UnixTools.csproj +++ b/src/XenoAtom.UnixTools/XenoAtom.UnixTools.csproj @@ -11,14 +11,14 @@ - This is a default project description + This project provides a set of Unix tools for .NET 8.0+. Alexandre Mutel en-US Alexandre Mutel - tag1;tag2;tag3 + unix;cpio readme.md XenoAtom.UnixTools.png - https://github.com/xoofx/XenoAtom.UnixTools + https://github.com/XenoAtom/XenoAtom.UnixTools BSD-2-Clause true