JobManager/Archiver/Lib/ArchiveDecoder.cs
2024-06-01 20:41:42 +09:00

86 lines
2.7 KiB
C#

using PacketIO;
namespace Archiver.Lib;
public static class ArchiveDecoder
{
public static async ValueTask Decode(string inputPath, string outputPath)
{
if (!File.Exists(inputPath))
{
throw new FileNotFoundException($"{inputPath} does not exist", inputPath);
}
FileAttributes attributes = File.GetAttributes(inputPath);
if (attributes.HasFlag(FileAttributes.Directory))
{
throw new IOException("Target does not file.");
}
using (FileStream fs = new FileStream(inputPath, FileMode.Open))
{
byte[] buffer = new byte[ArchiveEncoder.CreateFileHeader().Length];
await fs.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
if (!buffer.SequenceEqual(ArchiveEncoder.CreateFileHeader()))
{
throw new IOException("Not supported file type.");
}
await ReadFile(fs, outputPath).ConfigureAwait(false);
}
}
private static async ValueTask ReadFile(Stream stream, string outputPath)
{
IPacketFile? file = await TreePacketFile.ReadTreeFile(stream).ConfigureAwait(false);
if (file is null)
{
return;
}
await OutputFile(file, outputPath).ConfigureAwait(false);
await ReadFile(stream, outputPath).ConfigureAwait(false);
}
private static async ValueTask OutputFile(IPacketFile file, string outputPath)
{
switch (file.GetFileType())
{
case PacketFileType.Directory:
{
string dirPath = Path.Combine(outputPath, file.GetFileName());
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
foreach (IPacketFile inFile in file.EnumerableFiles())
{
await OutputFile(inFile, dirPath).ConfigureAwait(false);
}
break;
}
case PacketFileType.File:
{
string filePath = Path.Combine(outputPath, file.GetFileName());
using (FileStream outputStream = new FileStream(filePath, FileMode.OpenOrCreate))
{
PacketFile pfile = (PacketFile) file;
byte[] buffer = new byte[8192];
int c;
do
{
c = await pfile.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
await outputStream.WriteAsync(buffer, 0, c).ConfigureAwait(false);
} while (c > 0);
}
break;
}
}
file.Dispose();
}
}