From 0a5b39b217efe4619defd2d4de11a22bdb430852 Mon Sep 17 00:00:00 2001 From: nub31 Date: Tue, 10 Feb 2026 23:37:37 +0100 Subject: [PATCH] pack/unpack class --- compiler/NubLib.cs | 62 +++++++++++++++++++++++++++++++++++++++++++++ compiler/Program.cs | 61 +++----------------------------------------- 2 files changed, 65 insertions(+), 58 deletions(-) create mode 100644 compiler/NubLib.cs diff --git a/compiler/NubLib.cs b/compiler/NubLib.cs new file mode 100644 index 0000000..98d5927 --- /dev/null +++ b/compiler/NubLib.cs @@ -0,0 +1,62 @@ +using System.IO.Compression; +using System.Text.Json; + +namespace Compiler; + +public class NubLib +{ + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true, + }; + + public static void Pack(string outputPath, string archivePath, Manifest manifest) + { + using var fs = new FileStream(outputPath, FileMode.Create); + using var zip = new ZipArchive(fs, ZipArchiveMode.Create); + + var manifestEntry = zip.CreateEntry("manifest.json"); + using (var writer = new StreamWriter(manifestEntry.Open())) + { + var serialized = JsonSerializer.Serialize(manifest, JsonOptions); + + writer.Write(serialized); + } + + var archiveEntry = zip.CreateEntry("lib.a"); + + using var entryStream = archiveEntry.Open(); + using var fileStream = File.OpenRead(archivePath); + + fileStream.CopyTo(entryStream); + } + + public static NublibLoadResult Unpack(string nublibPath) + { + using var fs = new FileStream(nublibPath, FileMode.Open, FileAccess.Read); + using var zip = new ZipArchive(fs, ZipArchiveMode.Read); + + var manifestEntry = zip.GetEntry("manifest.json") ?? throw new FileNotFoundException("Manifest not found in nublib", "manifest.json"); + + Manifest manifest; + using (var reader = new StreamReader(manifestEntry.Open())) + { + var json = reader.ReadToEnd(); + manifest = JsonSerializer.Deserialize(json, JsonOptions) ?? throw new InvalidDataException("Failed to deserialize manifest.json"); + } + + var archiveEntry = zip.Entries.FirstOrDefault(e => e.Name.EndsWith(".a")) ?? throw new FileNotFoundException("Archive not found in nublib", "*.a"); + + string tempArchivePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".a"); + using (var entryStream = archiveEntry.Open()) + using (var tempFile = File.Create(tempArchivePath)) + { + entryStream.CopyTo(tempFile); + } + + return new NublibLoadResult(manifest, tempArchivePath); + } + + public record NublibLoadResult(Manifest Manifest, string ArchivePath); +} \ No newline at end of file diff --git a/compiler/Program.cs b/compiler/Program.cs index b365dac..c16fade 100644 --- a/compiler/Program.cs +++ b/compiler/Program.cs @@ -1,6 +1,4 @@ using System.Diagnostics; -using System.IO.Compression; -using System.Text.Json; using Compiler; var nubFiles = new List(); @@ -66,7 +64,7 @@ var archivePaths = new List(); foreach (var libPath in libFiles) { - var lib = ReadNublib(libPath); + var lib = NubLib.Unpack(libPath); archivePaths.Add(lib.ArchivePath); moduleGraphBuilder.AddManifest(lib.Manifest); } @@ -137,7 +135,7 @@ if (compileLib) File.WriteAllText(".build/out.c", output); Process.Start("gcc", ["-Og", "-fvisibility=hidden", "-fno-builtin", "-c", "-o", ".build/out.o", ".build/out.c", .. archivePaths]).WaitForExit(); Process.Start("ar", ["rcs", ".build/out.a", ".build/out.o"]).WaitForExit(); - WriteNublib(".build/out.nublib", ".build/out.a", moduleGraph.CreateManifest()); + NubLib.Pack(".build/out.nublib", ".build/out.a", moduleGraph.CreateManifest()); } else { @@ -161,57 +159,4 @@ static void CleanDirectory(string dirName) CleanDirectory(subdir.FullName); subdir.Delete(); } -} - -static void WriteNublib(string outputPath, string archivePath, Manifest manifest) -{ - using var fs = new FileStream(outputPath, FileMode.Create); - using var zip = new ZipArchive(fs, ZipArchiveMode.Create); - - var serialized = JsonSerializer.Serialize(manifest, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true, - }); - - var manifestEntry = zip.CreateEntry("manifest.json"); - using (var writer = new StreamWriter(manifestEntry.Open())) - { - writer.Write(serialized); - } - - var archiveEntry = zip.CreateEntry("lib.a"); - - using var entryStream = archiveEntry.Open(); - using var fileStream = File.OpenRead(archivePath); - - fileStream.CopyTo(entryStream); -} - -static NublibLoadResult ReadNublib(string nublibPath) -{ - using var fs = new FileStream(nublibPath, FileMode.Open, FileAccess.Read); - using var zip = new ZipArchive(fs, ZipArchiveMode.Read); - - var manifestEntry = zip.GetEntry("manifest.json") ?? throw new FileNotFoundException("Manifest not found in nublib", "manifest.json"); - - Manifest manifest; - using (var reader = new StreamReader(manifestEntry.Open())) - { - var json = reader.ReadToEnd(); - manifest = JsonSerializer.Deserialize(json) ?? throw new InvalidDataException("Failed to deserialize manifest.json"); - } - - var archiveEntry = zip.Entries.FirstOrDefault(e => e.Name.EndsWith(".a")) ?? throw new FileNotFoundException("Archive not found in nublib", "*.a"); - - string tempArchivePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".a"); - using (var entryStream = archiveEntry.Open()) - using (var tempFile = File.Create(tempArchivePath)) - { - entryStream.CopyTo(tempFile); - } - - return new NublibLoadResult(manifest, tempArchivePath); -} - -public record NublibLoadResult(Manifest Manifest, string ArchivePath); +} \ No newline at end of file