From 4d65732b4c1ee34206b4bc26dda8d5ab4259093c Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 1 Sep 2025 04:27:37 +0100 Subject: [PATCH] [ARC] Implement identification and information. --- Aaru.Archives/Arc/Info.cs | 121 +++++++++++++++++++++++++++++ Aaru.Archives/Arc/Unimplemented.cs | 9 --- 2 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 Aaru.Archives/Arc/Info.cs diff --git a/Aaru.Archives/Arc/Info.cs b/Aaru.Archives/Arc/Info.cs new file mode 100644 index 000000000..4eb2788c4 --- /dev/null +++ b/Aaru.Archives/Arc/Info.cs @@ -0,0 +1,121 @@ +using System.IO; +using System.Text; +using Aaru.CommonTypes.Interfaces; +using Aaru.Helpers; +using Aaru.Logging; + +namespace Aaru.Archives; + +public sealed partial class Arc +{ +#region IArchive Members + + /// + public bool Identify(IFilter filter) + { + if(filter.DataForkLength < Marshal.SizeOf
()) return false; + + Stream stream = filter.GetDataForkStream(); + stream.Position = 0; + + byte[] hdr = new byte[Marshal.SizeOf
()]; + + stream.ReadExactly(hdr, 0, hdr.Length); + + Header header = Marshal.ByteArrayToStructureLittleEndian
(hdr); + + // Not a valid marker + if(header.marker != MARKER) return false; + + switch(header.method) + { + // Not a valid compression method + case > 12 and < 20: + // Not a valid informational item + case > 22 and < 30: + // Not a valid control item + case > 31: + return false; + } + + for(int i = 0; i < 11; i++) + + // Not a valid filename character + { + if(header.filename[i] > 0 && header.filename[i] < 0x20) return false; + } + + // If the filename is not 8.3, it's probably not an ARC file, but maybe it is in MVS/UNIX? + if(header.filename[11] != 0) return false; + + // Compressed size is larger than file size + // Hope for the best + return header.compressed < stream.Length; + } + + /// + public void GetInformation(IFilter filter, Encoding encoding, out string information) + { + information = ""; + + if(filter.DataForkLength < Marshal.SizeOf
()) return; + + Stream stream = filter.GetDataForkStream(); + stream.Position = 0; + + byte[] hdr = new byte[Marshal.SizeOf
()]; + + stream.ReadExactly(hdr, 0, hdr.Length); + + Header header = Marshal.ByteArrayToStructureLittleEndian
(hdr); + + AaruLogging.Debug(MODULE_NAME, "[navy]header.marker[/] = [teal]0x{0:X2}[/]", header.marker); + AaruLogging.Debug(MODULE_NAME, "[navy]header.method[/] = [teal]{0}[/]", header.method); + + AaruLogging.Debug(MODULE_NAME, + "[navy]header.filename[/] = [green]\"{0}\"[/]", + StringHandlers.CToString(header.filename)); + + AaruLogging.Debug(MODULE_NAME, "[navy]header.compressed[/] = [teal]{0}[/]", header.compressed); + AaruLogging.Debug(MODULE_NAME, "[navy]header.date[/] = [teal]{0}[/]", header.date); + AaruLogging.Debug(MODULE_NAME, "[navy]header.time[/] = [teal]{0}[/]", header.time); + AaruLogging.Debug(MODULE_NAME, "[navy]header.crc[/] = [teal]0x{0:X4}[/]", header.crc); + AaruLogging.Debug(MODULE_NAME, "[navy]header.uncompressed[/] = [teal]{0}[/]", header.uncompressed); + + // Not a valid marker + if(header.marker != MARKER) return; + + switch(header.method) + { + // Not a valid compression method + case > 12 and < 20: + // Not a valid informational item + case > 22 and < 30: + // Not a valid control item + case > 31: + return; + } + + for(int i = 0; i < 11; i++) + + // Not a valid filename character + { + if(header.filename[i] > 0 && header.filename[i] < 0x20) return; + } + + // If the filename is not 8.3, it's probably not an ARC file, but maybe it is in MVS/UNIX? + if(header.filename[11] != 0) return; + + // Compressed size is larger than file size + if(header.compressed >= stream.Length) return; + + // Hope for the best + + var sb = new StringBuilder(); + sb.AppendLine("[bold][blue]ARC archive[/][/]"); + + information = sb.ToString(); + } + +#endregion +} \ No newline at end of file diff --git a/Aaru.Archives/Arc/Unimplemented.cs b/Aaru.Archives/Arc/Unimplemented.cs index a162c8e0b..72a57f934 100644 --- a/Aaru.Archives/Arc/Unimplemented.cs +++ b/Aaru.Archives/Arc/Unimplemented.cs @@ -12,9 +12,6 @@ public sealed partial class Arc { #region IArchive Members - /// - public bool Identify(IFilter filter) => throw new NotImplementedException(); - /// public ErrorNumber Open(IFilter filter, Encoding encoding) => throw new NotImplementedException(); @@ -54,11 +51,5 @@ public sealed partial class Arc /// public ErrorNumber GetEntry(int entryNumber, out IFilter filter) => throw new NotImplementedException(); - /// - public void GetInformation(IFilter filter, Encoding encoding, out string information) - { - throw new NotImplementedException(); - } - #endregion } \ No newline at end of file