diff --git a/Rhea.Nar.Validator/Program.cs b/Rhea.Nar.Validator/Program.cs
new file mode 100644
index 0000000..14f9c22
--- /dev/null
+++ b/Rhea.Nar.Validator/Program.cs
@@ -0,0 +1,114 @@
+using System.Diagnostics;
+using ArcaneLibs;
+using ArcaneLibs.Extensions;
+using Rhea.Nar;
+
+// A simple app to compare output between cppnix/Lix and the NAR serializer
+int maxVerifySize = 1024 * 1024 * 1024;
+
+// return;
+// while (true)
+// foreach (var srcPath in (string[])[
+// "/etc/nix/nix.conf",
+// FileUtils.GetBinDir() + "/Rhea.runtimeconfig.json",
+// "/etc/nix",
+// ".",
+// "/nix/store/06d2xkrl3h1pbyg3m1whz1mvhafqgsqq-source",
+// "/nix/store/0l93s9x3z2s9p4r58jls0xiyk64hwkxz-source",
+// "/nix/store/2g4sa9xcir93nckzib9iq1ky6ly6azgw-7j1q60m17gf95k3s0gk2qvjqygnp1q36-source"
+// ])
+// foreach (var srcPath in (string[])["/nix/store/7j1q60m17gf95k3s0gk2qvjqygnp1q36-source"])
+Parallel.ForEach(FileUtils.EnumerateDirectory("/nix/store")
+ .Where(x => x is DirectoryInfo)
+ .Select(x => x.FullName),
+ new() { MaxDegreeOfParallelism = 64 },
+ srcPath =>
+ // foreach (var srcPath in FileUtils.EnumerateDirectory("/nix/store").Select(x=>x.FullName))
+ {
+ var sw = Stopwatch.StartNew();
+ TimeSpan oldTime, newTime;
+ var log = "";
+ log += ($"\n - {srcPath}:");
+ bool tooLarge = false;
+ // Console.WriteLine($"Original {srcPath}:");
+
+ var origBuf = new List<byte>();
+ var nixProcess = Process.Start(new ProcessStartInfo("nix", ["nar", "dump-path", srcPath])
+ {
+ RedirectStandardOutput = true
+ });
+ int b;
+ byte[] oldBuf = new byte[16384];
+ while ((b = nixProcess.StandardOutput.BaseStream.Read(oldBuf)) != 0)
+ {
+ if (!tooLarge)
+ {
+ if (origBuf.Count < maxVerifySize)
+ origBuf.AddRange(oldBuf[..b]);
+ else tooLarge = true;
+ }
+ // Console.WriteLine(b + " @ " + sw.Elapsed + " -> " + Util.BytesToString(origBuf.Count));
+ // Thread.Sleep(1);
+ }
+
+ // origBuf.ToArray().HexDump(64);
+ oldTime = sw.GetElapsedAndRestart();
+
+ // Console.WriteLine($"\nNew {srcPath}:");
+ List<byte> tbuf = [];
+ // List<byte> buf = [];
+ foreach (var chunk in new NarWriter().GetNarStreamContents(srcPath))
+ {
+ // Console.WriteLine($"ret Chunk({chunk.Length})");
+ if (!tooLarge)
+ {
+ if (tbuf.Count < maxVerifySize)
+ tbuf.AddRange(chunk);
+ else tooLarge = true;
+ }
+ // buf.AddRange(chunk);
+ // while (buf.Count > 64)
+ // {
+ // byte[] data = buf[..64].ToArray();
+ // buf = buf[64..];
+ // data.HexDump(64);
+ // }
+ }
+
+ // buf.ToArray().HexDump(64);
+ newTime = sw.GetElapsedAndRestart();
+
+ log += ($"\nOld time: {oldTime}, new time: {newTime}");
+ if (!tooLarge)
+ {
+ log += ("\nIs equal: " + origBuf.SequenceEqual(tbuf));
+ if (!origBuf.SequenceEqual(tbuf))
+ {
+ // File.WriteAllBytes("a", origBuf.ToArray().AsHexString().AsBytes().ToArray());
+ // File.WriteAllBytes("b", tbuf.ToArray().AsHexString().AsBytes().ToArray());
+ var origStdout = Console.Out;
+ using (var fs = File.OpenWrite("a"))
+ {
+ using var fsw = new StreamWriter(fs);
+ Console.SetOut(fsw);
+ origBuf.HexDump(width: 16, colorize: false);
+ Console.SetOut(origStdout);
+ }
+
+ using (var fs = File.OpenWrite("b"))
+ {
+ using var fsw = new StreamWriter(fs);
+ Console.SetOut(fsw);
+ tbuf.HexDump(width: 16, colorize: false);
+ Console.SetOut(origStdout);
+ }
+
+ Console.WriteLine(log);
+ Environment.Exit(0);
+ }
+ }
+ else log += "\nToo large to check consistency";
+
+ Console.WriteLine(log);
+ }
+);
\ No newline at end of file
|