86 lines
2.7 KiB
C#
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();
|
|
}
|
|
}
|