Files
Aaru/Aaru.Archives/Amg/Open.cs

109 lines
3.1 KiB
C#
Raw Normal View History

2025-09-05 03:07:50 +01:00
using System.IO;
using System.Text;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.Helpers;
namespace Aaru.Archives;
public sealed partial class Amg
{
#region IArchive Members
/// <inheritdoc />
public ErrorNumber Open(IFilter filter, Encoding encoding)
{
encoding ??= Encoding.ASCII;
if(filter.DataForkLength < Marshal.SizeOf<ArcHeader>()) return ErrorNumber.InvalidArgument;
_stream = filter.GetDataForkStream();
_stream.Position = 0;
var hdr = new byte[Marshal.SizeOf<ArcHeader>()];
2025-09-05 03:07:50 +01:00
_stream.ReadExactly(hdr, 0, hdr.Length);
ArcHeader header = Marshal.ByteArrayToStructureLittleEndian<ArcHeader>(hdr);
// Not a valid magic
if(header.magic != ARC_MAGIC) return ErrorNumber.InvalidArgument;
// Skip comment
_stream.Position += header.commentLength;
int fileHeaderLen = Marshal.SizeOf<FileHeader>();
_files = [];
while(_stream.Position + fileHeaderLen < _stream.Length)
{
var fileHdr = new byte[fileHeaderLen];
2025-09-05 03:07:50 +01:00
_stream.ReadExactly(fileHdr, 0, fileHdr.Length);
FileHeader fh = Marshal.ByteArrayToStructureLittleEndian<FileHeader>(fileHdr);
// Not a valid file magic
if(fh.magic != FILE_MAGIC) break;
var entry = new FileEntry
{
Attributes = (FileAttributes)fh.attr,
Compressed = (uint)(fh.compressed - fh.pathLength - fh.commentLength - fileHeaderLen),
Crc = fh.crc,
Flags = fh.flags,
LastWrite = DateHandlers.DosToDateTime(fh.date, fh.time),
Uncompressed = fh.uncompressed,
Filename = StringHandlers.CToString(fh.filename, encoding)
};
string extension = StringHandlers.CToString(fh.extension, encoding);
if(!string.IsNullOrEmpty(extension)) entry.Filename += "." + extension;
if(fh.pathLength > 0)
{
var buffer = new byte[fh.pathLength];
2025-09-05 03:07:50 +01:00
_stream.ReadExactly(buffer, 0, buffer.Length);
string path = StringHandlers.CToString(buffer, encoding);
path = path.Replace('\\', Path.DirectorySeparatorChar);
entry.Filename = Path.Combine(path, entry.Filename);
}
if(fh.commentLength > 0)
{
var buffer = new byte[fh.commentLength];
2025-09-05 03:07:50 +01:00
_stream.ReadExactly(buffer, 0, buffer.Length);
entry.Comment = StringHandlers.CToString(buffer, encoding);
}
entry.Offset = _stream.Position;
_files.Add(entry);
// Skip compressed data
_stream.Position += entry.Compressed;
}
Opened = true;
return ErrorNumber.NoError;
}
/// <inheritdoc />
public void Close()
{
// Already closed
if(!Opened) return;
_stream?.Close();
_files?.Clear();
_stream = null;
Opened = false;
}
#endregion
}