summary refs log tree commit diff
path: root/Rhea.Nar/NarWriter.cs
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-08-14 11:32:13 +0200
committerRory& <root@rory.gay>2026-08-14 11:32:13 +0200
commitcc7897a79a945626ea6d0c19e8a6b32cbf547d1d (patch)
treec8a92f52fae7b2ec06b78a04d73928ff727f383c /Rhea.Nar/NarWriter.cs
parentWorking directories (diff)
downloadRhea-cc7897a79a945626ea6d0c19e8a6b32cbf547d1d.tar.xz
Fix some consistency issues, some documentation
Diffstat (limited to 'Rhea.Nar/NarWriter.cs')
-rw-r--r--Rhea.Nar/NarWriter.cs80
1 files changed, 36 insertions, 44 deletions
diff --git a/Rhea.Nar/NarWriter.cs b/Rhea.Nar/NarWriter.cs

index 424f52a..49b5eb6 100644 --- a/Rhea.Nar/NarWriter.cs +++ b/Rhea.Nar/NarWriter.cs
@@ -1,31 +1,8 @@ -using System.IO.Enumeration; -using System.Runtime.InteropServices; using ArcaneLibs; using ArcaneLibs.Extensions; namespace Rhea.Nar; -public ref struct NarConsts -{ - public static readonly byte[] Header = NarWriter.GetLengthPrefixedPadded("nix-archive-1"u8); - - public static readonly byte[] LeftParen = NarWriter.GetLengthPrefixedPadded("("u8); - public static readonly byte[] RightParen = NarWriter.GetLengthPrefixedPadded(")"u8); - - public static readonly byte[] Regular = NarWriter.GetLengthPrefixedPadded("regular"u8); - public static readonly byte[] Directory = NarWriter.GetLengthPrefixedPadded("directory"u8); - public static readonly byte[] Symlink = NarWriter.GetLengthPrefixedPadded("symlink"u8); - - public static readonly byte[] Entry = NarWriter.GetLengthPrefixedPadded("entry"u8); - public static readonly byte[] Name = NarWriter.GetLengthPrefixedPadded("name"u8); - public static readonly byte[] Target = NarWriter.GetLengthPrefixedPadded("target"u8); - public static readonly byte[] Node = NarWriter.GetLengthPrefixedPadded("node"u8); - public static readonly byte[] Type = NarWriter.GetLengthPrefixedPadded("type"u8); - public static readonly byte[] Executable = NarWriter.GetLengthPrefixedPadded("executable"u8); - - public static readonly byte[] Contents = NarWriter.GetLengthPrefixedPadded("contents"u8); -} - public class NarWriter { public Span<byte> GetHeader() @@ -42,19 +19,19 @@ public class NarWriter public IEnumerable<byte[]> GetNarStreamContentsInner(string path) { FileAttributes fattr = File.GetAttributes(path); - if (fattr.HasFlag(FileAttributes.Directory)) - foreach (var chunk in GetNarDirectoryContents(new DirectoryInfo(path))) - yield return chunk; - else + var linkTarget = new FileInfo(path).LinkTarget; + if (string.IsNullOrWhiteSpace(linkTarget)) { - var linkTarget = new FileInfo(path).LinkTarget; - if (string.IsNullOrWhiteSpace(linkTarget)) - foreach (var chunk in GetNarFileContents(new FileInfo(path))) + if (fattr.HasFlag(FileAttributes.Directory)) + foreach (var chunk in GetNarDirectoryContents(new DirectoryInfo(path))) yield return chunk; else - foreach (var chunk in GetNarSymlinkContents(new FileInfo(path))) + foreach (var chunk in GetNarFileContents(new FileInfo(path))) yield return chunk; } + else + foreach (var chunk in GetNarSymlinkContents(new FileInfo(path))) + yield return chunk; } private IEnumerable<byte[]> GetNarDirectoryContents(DirectoryInfo de) @@ -62,15 +39,19 @@ public class NarWriter yield return NarConsts.LeftParen; yield return NarConsts.Type; yield return NarConsts.Directory; - - foreach (var fe in FileUtils.EnumerateDirectory(de.FullName).OrderBy(x => x.Name)) + + foreach (var fe in FileUtils.EnumerateDirectory(de.FullName) + // .OrderBy(x=>x is DirectoryInfo ? 0 : 1) + // .ThenBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase) + .OrderBy(x => x.Name, StringComparer.Ordinal) + ) { yield return NarConsts.Entry; yield return NarConsts.LeftParen; yield return NarConsts.Name; yield return GetLengthPrefixedPadded(fe.Name.AsBytes().ToArray()); - + yield return NarConsts.Node; foreach (var chunk in GetNarStreamContentsInner(fe.FullName)) yield return chunk; @@ -83,14 +64,26 @@ public class NarWriter private IEnumerable<byte[]> GetNarSymlinkContents(FileInfo fe) { - yield return NarConsts.LeftParen; + // yield return NarConsts.LeftParen; + // + // yield return NarConsts.Type; + // yield return NarConsts.Symlink; + // yield return NarConsts.Target; + // yield return GetLengthPrefixedPadded(fe.LinkTarget!.AsBytes().ToArray()); + // + // yield return NarConsts.RightParen; - yield return NarConsts.Type; - yield return NarConsts.Symlink; - yield return NarConsts.Target; - yield return GetLengthPrefixedPadded(fe.LinkTarget!.AsBytes().ToArray()); + yield return + [ + ..NarConsts.LeftParen, - yield return NarConsts.RightParen; + ..NarConsts.Type, + ..NarConsts.Symlink, + ..NarConsts.Target, + ..GetLengthPrefixedPadded(fe.LinkTarget!.AsBytes().ToArray()), + + ..NarConsts.RightParen + ]; } private IEnumerable<byte[]> GetNarFileContents(FileInfo fe) @@ -104,7 +97,10 @@ public class NarWriter || fe.UnixFileMode.HasFlag(UnixFileMode.GroupExecute) || fe.UnixFileMode.HasFlag(UnixFileMode.OtherExecute) ) + { yield return NarConsts.Executable; + yield return new byte[8]; + } var targetLength = Math.Ceiling(fe.Length / 8d) * 8UL; yield return NarConsts.Contents; @@ -135,11 +131,7 @@ public class NarWriter { byte[] unpadded = [..BitConverter.GetBytes((ulong)data.Length), .. data]; var targetLength = Math.Ceiling(unpadded.Length / 8d) * 8; - // Console.Write($"{unpadded.Length:X2} - "); - // unpadded.HexDump(); Array.Resize(ref unpadded, (int)targetLength); - // Console.Write($"{unpadded.Length:X2} - "); - // unpadded.HexDump(); return unpadded; }