mirror of
https://github.com/blueskythlikesclouds/SonicAudioTools.git
synced 2025-02-10 16:02:58 +01:00
108 lines
3.3 KiB
C#
108 lines
3.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.IO;
|
|
|
|
using SonicAudioLib.Archive;
|
|
|
|
namespace SonicAudioLib.IO
|
|
{
|
|
public class DataExtractor
|
|
{
|
|
public enum LoggingType
|
|
{
|
|
Progress,
|
|
Message,
|
|
}
|
|
|
|
private class Item
|
|
{
|
|
public object Source { get; set; }
|
|
public string DestinationFileName { get; set; }
|
|
public long Position { get; set; }
|
|
public long Length { get; set; }
|
|
public bool DecompressFromCriLayla { get; set; }
|
|
}
|
|
|
|
private List<Item> items = new List<Item>();
|
|
|
|
public int BufferSize { get; set; }
|
|
public bool EnableThreading { get; set; }
|
|
public int MaxThreads { get; set; }
|
|
|
|
public event ProgressChanged ProgressChanged;
|
|
|
|
public void Add(object source, string destinationFileName, long position, long length, bool decompressFromCriLayla = false)
|
|
{
|
|
items.Add(new Item { Source = source, DestinationFileName = destinationFileName, Position = position, Length = length, DecompressFromCriLayla = decompressFromCriLayla });
|
|
}
|
|
|
|
public void Run()
|
|
{
|
|
double progress = 0.0;
|
|
double factor = 100.0 / items.Count;
|
|
|
|
object lockTarget = new object();
|
|
|
|
Action<Item> action = item =>
|
|
{
|
|
if (ProgressChanged != null)
|
|
{
|
|
lock (lockTarget)
|
|
{
|
|
progress += factor;
|
|
ProgressChanged(this, new ProgressChangedEventArgs(progress));
|
|
}
|
|
}
|
|
|
|
FileInfo destinationFileName = new FileInfo(item.DestinationFileName);
|
|
|
|
if (!destinationFileName.Directory.Exists)
|
|
{
|
|
destinationFileName.Directory.Create();
|
|
}
|
|
|
|
using (Stream source =
|
|
item.Source is string fileName ? new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize) :
|
|
item.Source is byte[] byteArray ? new MemoryStream(byteArray) :
|
|
item.Source is Stream stream ? stream :
|
|
throw new ArgumentException("Unknown source in item", nameof(item.Source))
|
|
)
|
|
using (Stream destination = destinationFileName.Create())
|
|
{
|
|
if (item.DecompressFromCriLayla)
|
|
{
|
|
CriCpkArchive.Decompress(source, item.Position, destination);
|
|
}
|
|
|
|
else
|
|
{
|
|
EndianStream.CopyPartTo(source, destination, item.Position, item.Length, BufferSize);
|
|
}
|
|
}
|
|
};
|
|
|
|
if (EnableThreading)
|
|
{
|
|
Parallel.ForEach(items, new ParallelOptions { MaxDegreeOfParallelism = MaxThreads }, action);
|
|
}
|
|
|
|
else
|
|
{
|
|
items.ForEach(action);
|
|
}
|
|
|
|
items.Clear();
|
|
}
|
|
|
|
public DataExtractor()
|
|
{
|
|
BufferSize = 4096;
|
|
EnableThreading = true;
|
|
MaxThreads = 4;
|
|
}
|
|
}
|
|
}
|