mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Password protected archives support
This commit is contained in:
@@ -28,10 +28,11 @@ namespace ArCueDotNet
|
||||
StringWriter sw = new StringWriter();
|
||||
try
|
||||
{
|
||||
CUESheet cueSheet = new CUESheet(pathIn, config);
|
||||
CUESheet cueSheet = new CUESheet(config);
|
||||
cueSheet.Open(pathIn);
|
||||
cueSheet.GenerateFilenames(OutputAudioFormat.NoAudio, pathIn);
|
||||
cueSheet.AccurateRip = true;
|
||||
cueSheet.WriteAudioFiles(Path.GetDirectoryName(pathIn), CUEStyle.SingleFile, new SetStatus(ArCueSetStatus));
|
||||
cueSheet.WriteAudioFiles(Path.GetDirectoryName(pathIn), CUEStyle.SingleFile);
|
||||
cueSheet.GenerateAccurateRipLog(sw);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -41,8 +42,5 @@ namespace ArCueDotNet
|
||||
sw.Close();
|
||||
Console.Write(sw.ToString());
|
||||
}
|
||||
public static void ArCueSetStatus(string status, uint percentTrack, double percentDisk, string input, string output)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,12 @@
|
||||
<Compile Include="frmFilenameCorrector.Designer.cs">
|
||||
<DependentUpon>frmFilenameCorrector.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="frmPassword.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="frmPassword.Designer.cs">
|
||||
<DependentUpon>frmPassword.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="frmReport.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -140,6 +146,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>frmFilenameCorrector.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="frmPassword.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>frmPassword.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="frmReport.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>frmReport.cs</DependentUpon>
|
||||
|
||||
28
CUETools/Settings.cs
Normal file
28
CUETools/Settings.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace JDP.Properties {
|
||||
|
||||
|
||||
// This class allows you to handle specific events on the settings class:
|
||||
// The SettingChanging event is raised before a setting's value is changed.
|
||||
// The PropertyChanged event is raised after a setting's value is changed.
|
||||
// The SettingsLoaded event is raised after the setting values are loaded.
|
||||
// The SettingsSaving event is raised before the setting values are saved.
|
||||
internal sealed partial class Settings {
|
||||
|
||||
public Settings() {
|
||||
// // To add event handlers for saving and changing settings, uncomment the lines below:
|
||||
//
|
||||
// this.SettingChanging += this.SettingChangingEventHandler;
|
||||
//
|
||||
// this.SettingsSaving += this.SettingsSavingEventHandler;
|
||||
//
|
||||
}
|
||||
|
||||
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
|
||||
// Add code to handle the SettingChangingEvent event here.
|
||||
}
|
||||
|
||||
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
// Add code to handle the SettingsSaving event here.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,39 +57,55 @@ namespace JDP
|
||||
DateTime _startedAt;
|
||||
List<string> _batchPaths;
|
||||
|
||||
public string ShortenString(string input, int max)
|
||||
public static string ShortenString(string input, int max)
|
||||
{
|
||||
if (input.Length < max)
|
||||
return input;
|
||||
return "..." + input.Substring(input.Length - max);
|
||||
}
|
||||
|
||||
public void SetStatus(string status, uint percentTrack, double percentDisk, string input, string output)
|
||||
public void SetStatus(object sender, CUEToolsProgressEventArgs e)
|
||||
{
|
||||
this.BeginInvoke((MethodInvoker)delegate()
|
||||
{
|
||||
if (percentDisk == 0)
|
||||
if (e.percentDisk == 0)
|
||||
{
|
||||
_startedAt = DateTime.Now;
|
||||
Text = e.status;
|
||||
}
|
||||
else if (percentDisk > 0.02)
|
||||
else if (e.percentDisk > 0.02)
|
||||
{
|
||||
TimeSpan span = DateTime.Now - _startedAt;
|
||||
TimeSpan eta = new TimeSpan ((long) (span.Ticks/percentDisk));
|
||||
Text = String.Format("{0}, ETA {1}:{2:00}.", status, (int)eta.TotalMinutes, eta.Seconds);
|
||||
TimeSpan eta = new TimeSpan ((long) (span.Ticks/e.percentDisk));
|
||||
Text = String.Format("{0}, ETA {1}:{2:00}.", e.status, (int)eta.TotalMinutes, eta.Seconds);
|
||||
} else
|
||||
Text = status;
|
||||
progressBar1.Value = (int)percentTrack;
|
||||
progressBar2.Value = (int)(percentDisk*100);
|
||||
string inputSuffix = output != null ? "=>" : "";
|
||||
if (input == null)
|
||||
Text = e.status;
|
||||
progressBar1.Value = (int)e.percentTrack;
|
||||
progressBar2.Value = (int)(e.percentDisk*100);
|
||||
string inputSuffix = e.output != null ? "=>" : "";
|
||||
if (e.input == null)
|
||||
txtInputFile.Text = inputSuffix;
|
||||
else
|
||||
txtInputFile.Text = ShortenString(input, 120) + " " + inputSuffix;
|
||||
if (output == null)
|
||||
txtInputFile.Text = ShortenString(e.input, 120) + " " + inputSuffix;
|
||||
if (e.output == null)
|
||||
txtOutputFile.Text = "";
|
||||
else
|
||||
txtOutputFile.Text = ShortenString(output, 120);
|
||||
txtOutputFile.Text = ShortenString(e.output, 120);
|
||||
});
|
||||
}
|
||||
|
||||
private void PasswordRequired(object sender, ArchivePasswordRequiredEventArgs e)
|
||||
{
|
||||
this.Invoke((MethodInvoker)delegate()
|
||||
{
|
||||
frmPassword dlg = new frmPassword();
|
||||
if (dlg.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
e.Password = dlg.txtPassword.Text;
|
||||
e.ContinueOperation = true;
|
||||
}
|
||||
else
|
||||
e.ContinueOperation = false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,7 +115,59 @@ namespace JDP
|
||||
|
||||
try
|
||||
{
|
||||
cueSheet.WriteAudioFiles(Path.GetDirectoryName(pathOut), _cueStyle, new SetStatus(this.SetStatus));
|
||||
_startedAt = DateTime.Now;
|
||||
if (_batchPaths.Count != 0)
|
||||
pathIn = _batchPaths[0];
|
||||
|
||||
pathIn = Path.GetFullPath(pathIn);
|
||||
|
||||
textBox1.Text += "Processing " + pathIn + ":\r\n";
|
||||
textBox1.Select(0, 0);
|
||||
|
||||
string cueName;
|
||||
if (!File.Exists(pathIn))
|
||||
{
|
||||
if (!Directory.Exists(pathIn))
|
||||
throw new Exception("Input CUE Sheet not found.");
|
||||
if (!pathIn.EndsWith(new string(Path.DirectorySeparatorChar, 1)))
|
||||
pathIn = pathIn + Path.DirectorySeparatorChar;
|
||||
cueName = Path.GetFileNameWithoutExtension(Path.GetDirectoryName(pathIn)) + ".cue";
|
||||
}
|
||||
else
|
||||
cueName = Path.GetFileNameWithoutExtension(pathIn) + ".cue";
|
||||
|
||||
bool outputAudio = _accurateOffset || !_accurateRip;
|
||||
cueSheet.Open(pathIn);
|
||||
if (outputAudio)
|
||||
{
|
||||
bool pathFound = false;
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
string outDir = Path.Combine(Path.GetDirectoryName(pathIn), "CUEToolsOutput" + (i > 0 ? String.Format("({0})", i) : ""));
|
||||
if (!Directory.Exists(outDir))
|
||||
{
|
||||
Directory.CreateDirectory(outDir);
|
||||
pathOut = Path.Combine(outDir, cueName);
|
||||
pathFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pathFound)
|
||||
throw new Exception("Could not create a folder.");
|
||||
}
|
||||
else
|
||||
pathOut = Path.Combine(Path.GetDirectoryName(pathIn), cueName);
|
||||
cueSheet.GenerateFilenames(_audioFormat, pathOut);
|
||||
if (outputAudio)
|
||||
{
|
||||
if (_cueStyle == CUEStyle.SingleFileWithCUE)
|
||||
cueSheet.SingleFilename = Path.ChangeExtension(Path.GetFileName(pathOut), General.FormatExtension(_audioFormat));
|
||||
}
|
||||
|
||||
cueSheet.UsePregapForFirstTrackInSingleFile = false;
|
||||
cueSheet.AccurateRip = _accurateRip;
|
||||
cueSheet.AccurateOffset = _accurateOffset;
|
||||
cueSheet.WriteAudioFiles(Path.GetDirectoryName(pathOut), _cueStyle);
|
||||
this.Invoke((MethodInvoker)delegate()
|
||||
{
|
||||
if (_batchPaths.Count == 0)
|
||||
@@ -138,8 +206,10 @@ namespace JDP
|
||||
{
|
||||
Text = "Error: " + ex.Message;
|
||||
textBox1.Show();
|
||||
textBox1.Text += "Error: " + ex.Message + "\r\n";
|
||||
textBox1.Text += "----------------------------------------------------------\r\n";
|
||||
textBox1.Text += "Error";
|
||||
for (Exception e = ex; e != null; e = e.InnerException)
|
||||
textBox1.Text += ": " + e.Message;
|
||||
textBox1.Text += "\r\n----------------------------------------------------------\r\n";
|
||||
textBox1.Select(0, 0);
|
||||
});
|
||||
}
|
||||
@@ -164,62 +234,11 @@ namespace JDP
|
||||
|
||||
public void StartConvert()
|
||||
{
|
||||
CUESheet cueSheet;
|
||||
|
||||
try
|
||||
{
|
||||
_startedAt = DateTime.Now;
|
||||
|
||||
_workThread = null;
|
||||
if (_batchPaths.Count != 0)
|
||||
pathIn = _batchPaths[0];
|
||||
|
||||
pathIn = Path.GetFullPath(pathIn);
|
||||
|
||||
textBox1.Text += "Processing " + pathIn + ":\r\n";
|
||||
textBox1.Select (0,0);
|
||||
|
||||
string cueName;
|
||||
if (!File.Exists(pathIn))
|
||||
{
|
||||
if (!Directory.Exists (pathIn))
|
||||
throw new Exception("Input CUE Sheet not found.");
|
||||
if (!pathIn.EndsWith(new string(Path.DirectorySeparatorChar, 1)))
|
||||
pathIn = pathIn + Path.DirectorySeparatorChar;
|
||||
cueName = Path.GetFileNameWithoutExtension(Path.GetDirectoryName(pathIn)) + ".cue";
|
||||
} else
|
||||
cueName = Path.GetFileNameWithoutExtension(pathIn) + ".cue";
|
||||
|
||||
bool outputAudio = _accurateOffset || !_accurateRip;
|
||||
cueSheet = new CUESheet(pathIn, _config);
|
||||
if (outputAudio)
|
||||
{
|
||||
bool pathFound = false;
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
string outDir = Path.Combine(Path.GetDirectoryName (pathIn), "CUEToolsOutput" + (i > 0? String.Format("({0})",i) : ""));
|
||||
if (!Directory.Exists(outDir))
|
||||
{
|
||||
Directory.CreateDirectory(outDir);
|
||||
pathOut = Path.Combine(outDir, cueName);
|
||||
pathFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pathFound)
|
||||
throw new Exception("Could not create a folder.");
|
||||
} else
|
||||
pathOut = Path.Combine(Path.GetDirectoryName(pathIn), cueName);
|
||||
cueSheet.GenerateFilenames(_audioFormat, pathOut);
|
||||
if (outputAudio)
|
||||
{
|
||||
if (_cueStyle == CUEStyle.SingleFileWithCUE)
|
||||
cueSheet.SingleFilename = Path.ChangeExtension(Path.GetFileName (pathOut), General.FormatExtension (_audioFormat));
|
||||
}
|
||||
|
||||
cueSheet.UsePregapForFirstTrackInSingleFile = false;
|
||||
cueSheet.AccurateRip = _accurateRip;
|
||||
cueSheet.AccurateOffset = _accurateOffset;
|
||||
CUESheet cueSheet = new CUESheet(_config);
|
||||
cueSheet.PasswordRequired += new ArchivePasswordRequiredHandler(PasswordRequired);
|
||||
cueSheet.CUEToolsProgress += new CUEToolsProgressHandler(SetStatus);
|
||||
|
||||
_workThread = new Thread(WriteAudioFilesThread);
|
||||
_workClass = cueSheet;
|
||||
@@ -235,16 +254,6 @@ namespace JDP
|
||||
textBox1.Text += "----------------------------------------------------------\r\n";
|
||||
textBox1.Select(0, 0);
|
||||
}
|
||||
if ((_workThread == null) && (_batchPaths.Count != 0))
|
||||
{
|
||||
_batchPaths.RemoveAt(0);
|
||||
if (_batchPaths.Count == 0)
|
||||
{
|
||||
Text = "All done.";
|
||||
}
|
||||
else
|
||||
StartConvert();
|
||||
}
|
||||
}
|
||||
|
||||
private void frmBatch_Load(object sender, EventArgs e)
|
||||
|
||||
@@ -240,10 +240,11 @@ namespace JDP {
|
||||
}
|
||||
}
|
||||
|
||||
cueSheet = new CUESheet(pathIn, _config);
|
||||
|
||||
cueSheet = new CUESheet(_config);
|
||||
cueSheet.PasswordRequired += new ArchivePasswordRequiredHandler(PasswordRequired);
|
||||
cueSheet.WriteOffset = _writeOffset;
|
||||
|
||||
cueSheet.Open(pathIn);
|
||||
|
||||
UpdateOutputPath(cueSheet.Artist != "" ? cueSheet.Artist : "Unknown Artist", cueSheet.Title != "" ? cueSheet.Title : "Unknown Title");
|
||||
pathOut = txtOutputPath.Text;
|
||||
cueSheet.GenerateFilenames(SelectedOutputAudioFormat, pathOut);
|
||||
@@ -326,6 +327,22 @@ namespace JDP {
|
||||
}
|
||||
}
|
||||
|
||||
private void PasswordRequired(object sender, ArchivePasswordRequiredEventArgs e)
|
||||
{
|
||||
//if (this.InvokeRequired)
|
||||
// this.Invoke(this.PasswordRequired, sender, e);
|
||||
//this.Invoke((MethodInvoker)delegate()
|
||||
//{
|
||||
frmPassword dlg = new frmPassword();
|
||||
if (dlg.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
e.Password = dlg.txtPassword.Text;
|
||||
e.ContinueOperation = true;
|
||||
} else
|
||||
e.ContinueOperation = false;
|
||||
//});
|
||||
}
|
||||
|
||||
private void WriteAudioFilesThread(object o) {
|
||||
object[] p = (object[])o;
|
||||
|
||||
@@ -334,7 +351,8 @@ namespace JDP {
|
||||
CUEStyle cueStyle = (CUEStyle)p[2];
|
||||
|
||||
try {
|
||||
cueSheet.WriteAudioFiles(outDir, cueStyle, new SetStatus(this.SetStatus));
|
||||
cueSheet.CUEToolsProgress += new CUEToolsProgressHandler(SetStatus);
|
||||
cueSheet.WriteAudioFiles(outDir, cueStyle);
|
||||
this.Invoke((MethodInvoker)delegate() {
|
||||
if (_batchPaths.Count == 0)
|
||||
{
|
||||
@@ -390,11 +408,12 @@ namespace JDP {
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStatus(string status, uint percentTrack, double percentDisk, string input, string output) {
|
||||
public void SetStatus(object sender, CUEToolsProgressEventArgs e)
|
||||
{
|
||||
this.BeginInvoke((MethodInvoker)delegate() {
|
||||
toolStripStatusLabel1.Text = status;
|
||||
toolStripProgressBar1.Value = (int)percentTrack;
|
||||
toolStripProgressBar2.Value = (int)(percentDisk*100);
|
||||
toolStripStatusLabel1.Text = e.status;
|
||||
toolStripProgressBar1.Value = (int)e.percentTrack;
|
||||
toolStripProgressBar2.Value = (int)(e.percentDisk*100);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
72
CUETools/frmPassword.Designer.cs
generated
Normal file
72
CUETools/frmPassword.Designer.cs
generated
Normal file
@@ -0,0 +1,72 @@
|
||||
namespace JDP
|
||||
{
|
||||
partial class frmPassword
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmPassword));
|
||||
this.txtPassword = new System.Windows.Forms.TextBox();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// txtPassword
|
||||
//
|
||||
resources.ApplyResources(this.txtPassword, "txtPassword");
|
||||
this.txtPassword.Name = "txtPassword";
|
||||
this.txtPassword.UseSystemPasswordChar = true;
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
resources.ApplyResources(this.button1, "button1");
|
||||
this.button1.Name = "button1";
|
||||
this.button1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// frmPassword
|
||||
//
|
||||
this.AcceptButton = this.button1;
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.button1);
|
||||
this.Controls.Add(this.txtPassword);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "frmPassword";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.TopMost = true;
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button button1;
|
||||
public System.Windows.Forms.TextBox txtPassword;
|
||||
}
|
||||
}
|
||||
18
CUETools/frmPassword.cs
Normal file
18
CUETools/frmPassword.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace JDP
|
||||
{
|
||||
public partial class frmPassword : Form
|
||||
{
|
||||
public frmPassword()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
195
CUETools/frmPassword.resx
Normal file
195
CUETools/frmPassword.resx
Normal file
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="txtPassword.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Left, Right</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="txtPassword.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 12</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="txtPassword.MaxLength" type="System.Int32, mscorlib">
|
||||
<value>256</value>
|
||||
</data>
|
||||
<data name="txtPassword.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>350, 20</value>
|
||||
</data>
|
||||
<data name="txtPassword.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>txtPassword.Name" xml:space="preserve">
|
||||
<value>txtPassword</value>
|
||||
</data>
|
||||
<data name=">>txtPassword.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>txtPassword.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>txtPassword.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>304, 40</value>
|
||||
</data>
|
||||
<data name="button1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>58, 23</value>
|
||||
</data>
|
||||
<data name="button1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button1.Text" xml:space="preserve">
|
||||
<value>Ok</value>
|
||||
</data>
|
||||
<data name=">>button1.Name" xml:space="preserve">
|
||||
<value>button1</value>
|
||||
</data>
|
||||
<data name=">>button1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>6, 13</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>374, 75</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterParent</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Password required</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>frmPassword</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -194,8 +194,6 @@ namespace CUEToolsLib
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void SetStatus(string status, uint percentTrack, double percentDisk, string input, string output);
|
||||
|
||||
public enum CUEStyle {
|
||||
SingleFileWithCUE,
|
||||
SingleFile,
|
||||
@@ -396,6 +394,24 @@ namespace CUEToolsLib
|
||||
}
|
||||
}
|
||||
|
||||
public class CUEToolsProgressEventArgs
|
||||
{
|
||||
public string status = string.Empty;
|
||||
public uint percentTrack = 0;
|
||||
public double percentDisk = 0.0;
|
||||
public string input = string.Empty;
|
||||
public string output = string.Empty;
|
||||
}
|
||||
|
||||
public class ArchivePasswordRequiredEventArgs
|
||||
{
|
||||
public string Password = string.Empty;
|
||||
public bool ContinueOperation = true;
|
||||
}
|
||||
|
||||
public delegate void CUEToolsProgressHandler(object sender, CUEToolsProgressEventArgs e);
|
||||
public delegate void ArchivePasswordRequiredHandler(object sender, ArchivePasswordRequiredEventArgs e);
|
||||
|
||||
public class CUESheet {
|
||||
private bool _stop, _pause;
|
||||
private List<CUELine> _attributes;
|
||||
@@ -423,35 +439,23 @@ namespace CUEToolsLib
|
||||
string _cddbDiscIdTag;
|
||||
private bool _isArchive;
|
||||
private string _archivePath;
|
||||
private string _archivePassword;
|
||||
private CUEToolsProgressEventArgs _progress;
|
||||
|
||||
public CUESheet(string pathIn, CUEConfig config)
|
||||
public event ArchivePasswordRequiredHandler PasswordRequired;
|
||||
public event CUEToolsProgressHandler CUEToolsProgress;
|
||||
|
||||
public CUESheet(CUEConfig config)
|
||||
{
|
||||
_config = config;
|
||||
|
||||
hdcdDecoder = null;
|
||||
if (_config.detectHDCD)
|
||||
{
|
||||
try { hdcdDecoder = new HDCDDotNet.HDCDDotNet(2, 44100, _config.decodeHDCD); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
string cueDir, lineStr, command, pathAudio, fileType;
|
||||
CUELine line;
|
||||
TrackInfo trackInfo;
|
||||
int tempTimeLength, timeRelativeToFileStart, absoluteFileStartTime;
|
||||
int fileTimeLengthSamples, fileTimeLengthFrames, i, trackNumber;
|
||||
bool seenFirstFileIndex, seenDataTrack;
|
||||
List<IndexInfo> indexes;
|
||||
IndexInfo indexInfo;
|
||||
SourceInfo sourceInfo;
|
||||
NameValueCollection _trackTags = null;
|
||||
|
||||
_stop = false;
|
||||
_pause = false;
|
||||
_progress = new CUEToolsProgressEventArgs();
|
||||
_attributes = new List<CUELine>();
|
||||
_tracks = new List<TrackInfo>();
|
||||
_sources = new List<SourceInfo>();
|
||||
_sourcePaths = new List<string>();
|
||||
_albumTags = new NameValueCollection();
|
||||
_stop = false;
|
||||
_pause = false;
|
||||
_cuePath = null;
|
||||
_paddedToFrame = false;
|
||||
_truncated4608 = false;
|
||||
@@ -461,20 +465,37 @@ namespace CUEToolsLib
|
||||
_appliedWriteOffset = false;
|
||||
_dataTrackLength = null;
|
||||
_minDataTrackLength = null;
|
||||
_albumTags = new NameValueCollection();
|
||||
hdcdDecoder = null;
|
||||
_hasEmbeddedCUESheet = false;
|
||||
_isArchive = false;
|
||||
accDisks = new List<AccDisk>();
|
||||
}
|
||||
|
||||
public void Open(string pathIn)
|
||||
{
|
||||
if (_config.detectHDCD)
|
||||
{
|
||||
try { hdcdDecoder = new HDCDDotNet.HDCDDotNet(2, 44100, _config.decodeHDCD); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
string cueDir, lineStr, command, pathAudio = null, fileType;
|
||||
CUELine line;
|
||||
TrackInfo trackInfo;
|
||||
int tempTimeLength, timeRelativeToFileStart, absoluteFileStartTime;
|
||||
int fileTimeLengthSamples, fileTimeLengthFrames, i, trackNumber;
|
||||
bool seenFirstFileIndex = false, seenDataTrack = false;
|
||||
List<IndexInfo> indexes = new List<IndexInfo>();
|
||||
IndexInfo indexInfo;
|
||||
SourceInfo sourceInfo;
|
||||
NameValueCollection _trackTags = null;
|
||||
|
||||
cueDir = Path.GetDirectoryName(pathIn);
|
||||
pathAudio = null;
|
||||
indexes = new List<IndexInfo>();
|
||||
trackInfo = null;
|
||||
absoluteFileStartTime = 0;
|
||||
fileTimeLengthSamples = 0;
|
||||
fileTimeLengthFrames = 0;
|
||||
trackNumber = 0;
|
||||
seenFirstFileIndex = false;
|
||||
seenDataTrack = false;
|
||||
accDisks = new List<AccDisk>();
|
||||
_hasEmbeddedCUESheet = false;
|
||||
_isArchive = false;
|
||||
|
||||
TextReader sr;
|
||||
|
||||
@@ -494,6 +515,7 @@ namespace CUEToolsLib
|
||||
else if (Path.GetExtension(pathIn).ToLower() == ".rar")
|
||||
{
|
||||
Unrar _unrar = new Unrar();
|
||||
_unrar.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
|
||||
string cueName = null, cueText = null;
|
||||
_unrar.Open(pathIn, Unrar.OpenMode.List);
|
||||
while (_unrar.ReadHeader())
|
||||
@@ -508,15 +530,16 @@ namespace CUEToolsLib
|
||||
}
|
||||
_unrar.Close();
|
||||
if (cueName != null)
|
||||
try
|
||||
{
|
||||
RarStream rarStream = new RarStream(pathIn, cueName);
|
||||
rarStream.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
|
||||
StreamReader cueReader = new StreamReader(rarStream, CUESheet.Encoding);
|
||||
cueText = cueReader.ReadToEnd();
|
||||
cueReader.Close();
|
||||
rarStream.Close();
|
||||
if (cueText == "")
|
||||
throw new Exception("Empty cue sheet.");
|
||||
}
|
||||
catch { }
|
||||
if (cueText == null)
|
||||
throw new Exception("Input archive doesn't contain a cue sheet.");
|
||||
sr = new StringReader(cueText);
|
||||
@@ -864,6 +887,49 @@ namespace CUEToolsLib
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowProgress(string status, uint percentTrack, double percentDisk, string input, string output)
|
||||
{
|
||||
if (this.CUEToolsProgress == null)
|
||||
return;
|
||||
_progress.status = status;
|
||||
_progress.percentTrack = percentTrack;
|
||||
_progress.percentDisk = percentDisk;
|
||||
_progress.input = input;
|
||||
_progress.output = output;
|
||||
this.CUEToolsProgress(this, _progress);
|
||||
}
|
||||
|
||||
#if !MONO
|
||||
private void unrar_ExtractionProgress(object sender, ExtractionProgressEventArgs e)
|
||||
{
|
||||
_progress.percentTrack = (uint) Math.Round(e.PercentComplete);
|
||||
this.CUEToolsProgress(this, _progress);
|
||||
}
|
||||
|
||||
private void unrar_PasswordRequired(object sender, PasswordRequiredEventArgs e)
|
||||
{
|
||||
if (_archivePassword != null)
|
||||
{
|
||||
e.ContinueOperation = true;
|
||||
e.Password = _archivePassword;
|
||||
return;
|
||||
}
|
||||
if (this.PasswordRequired != null)
|
||||
{
|
||||
ArchivePasswordRequiredEventArgs e1 = new ArchivePasswordRequiredEventArgs();
|
||||
this.PasswordRequired(this, e1);
|
||||
if (e1.ContinueOperation && e1.Password != "")
|
||||
{
|
||||
_archivePassword = e1.Password;
|
||||
e.ContinueOperation = true;
|
||||
e.Password = e1.Password;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IOException("Password is required for extraction.");
|
||||
}
|
||||
#endif
|
||||
|
||||
public string GetCommonTag(string tagName)
|
||||
{
|
||||
if (_hasEmbeddedCUESheet || _hasSingleFilename)
|
||||
@@ -1013,10 +1079,13 @@ namespace CUEToolsLib
|
||||
{
|
||||
IAudioSource audioSource;
|
||||
|
||||
ShowProgress("Opening source file...", 0, 0.0, path, null);
|
||||
#if !MONO
|
||||
if (_isArchive)
|
||||
{
|
||||
RarStream IO = new RarStream(_archivePath, path);
|
||||
IO.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
|
||||
IO.ExtractionProgress += new ExtractionProgressHandler(unrar_ExtractionProgress);
|
||||
audioSource = AudioReadWrite.GetAudioSource(path, IO);
|
||||
} else
|
||||
#endif
|
||||
@@ -1618,7 +1687,7 @@ namespace CUEToolsLib
|
||||
outTracksMatch = bestTracksMatch;
|
||||
}
|
||||
|
||||
public void WriteAudioFiles(string dir, CUEStyle style, SetStatus statusDel) {
|
||||
public void WriteAudioFiles(string dir, CUEStyle style) {
|
||||
string[] destPaths;
|
||||
int[] destLengths;
|
||||
bool htoaToFile = ((style == CUEStyle.GapsAppended) && _config.preserveHTOA &&
|
||||
@@ -1656,7 +1725,7 @@ namespace CUEToolsLib
|
||||
bool SkipOutput = false;
|
||||
|
||||
if (_accurateRip) {
|
||||
statusDel((string)"Contacting AccurateRip database...", 0, 0, null, null);
|
||||
ShowProgress((string)"Contacting AccurateRip database...", 0, 0, null, null);
|
||||
if (!_dataTrackLength.HasValue && _minDataTrackLength.HasValue && _accurateRipId == _accurateRipIdActual && _config.bruteForceDTL)
|
||||
{
|
||||
uint minDTL = _minDataTrackLength.Value;
|
||||
@@ -1667,13 +1736,13 @@ namespace CUEToolsLib
|
||||
ContactAccurateRip();
|
||||
if (accResult != HttpStatusCode.NotFound)
|
||||
break;
|
||||
statusDel((string)"Contacting AccurateRip database...", 0, (dtl-minDTL)/75.0, null, null);
|
||||
ShowProgress((string)"Contacting AccurateRip database...", 0, (dtl - minDTL) / 75.0, null, null);
|
||||
lock (this) {
|
||||
if (_stop)
|
||||
throw new StopException();
|
||||
if (_pause)
|
||||
{
|
||||
statusDel("Paused...", 0, 0, null, null);
|
||||
ShowProgress("Paused...", 0, 0, null, null);
|
||||
Monitor.Wait(this);
|
||||
}
|
||||
else
|
||||
@@ -1714,7 +1783,7 @@ namespace CUEToolsLib
|
||||
else if (_accurateOffset)
|
||||
{
|
||||
_writeOffset = 0;
|
||||
WriteAudioFilesPass(dir, style, statusDel, destPaths, destLengths, htoaToFile, true);
|
||||
WriteAudioFilesPass(dir, style, destPaths, destLengths, htoaToFile, true);
|
||||
|
||||
uint tracksMatch;
|
||||
int bestOffset;
|
||||
@@ -1749,12 +1818,12 @@ namespace CUEToolsLib
|
||||
if (style != CUEStyle.SingleFileWithCUE && style != CUEStyle.SingleFile && _config.createM3U)
|
||||
WriteM3U(Path.ChangeExtension(_cuePath, ".m3u"), style);
|
||||
}
|
||||
WriteAudioFilesPass(dir, style, statusDel, destPaths, destLengths, htoaToFile, verifyOnly);
|
||||
WriteAudioFilesPass(dir, style, destPaths, destLengths, htoaToFile, verifyOnly);
|
||||
}
|
||||
|
||||
if (_accurateRip)
|
||||
{
|
||||
statusDel((string)"Generating AccurateRip report...", 0, 0, null, null);
|
||||
ShowProgress((string)"Generating AccurateRip report...", 0, 0, null, null);
|
||||
if (!_accurateOffset && _config.writeArTagsOnVerify && _writeOffset == 0 && !_isArchive)
|
||||
{
|
||||
uint tracksMatch;
|
||||
@@ -1930,7 +1999,7 @@ namespace CUEToolsLib
|
||||
audioDest.SetTags(destTags);
|
||||
}
|
||||
|
||||
public void WriteAudioFilesPass(string dir, CUEStyle style, SetStatus statusDel, string[] destPaths, int[] destLengths, bool htoaToFile, bool noOutput)
|
||||
public void WriteAudioFilesPass(string dir, CUEStyle style, string[] destPaths, int[] destLengths, bool htoaToFile, bool noOutput)
|
||||
{
|
||||
const int buffLen = 16384;
|
||||
int iTrack, iIndex;
|
||||
@@ -2024,7 +2093,7 @@ namespace CUEToolsLib
|
||||
diskLength += _tracks[iTrack].IndexLengths[iIndex] * 588;
|
||||
|
||||
|
||||
statusDel(String.Format("{2} track {0:00} ({1:00}%)...", 0, 0, noOutput ? "Verifying" : "Writing"), 0, 0.0, null, null);
|
||||
ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", 0, 0, noOutput ? "Verifying" : "Writing"), 0, 0.0, null, null);
|
||||
|
||||
for (iTrack = 0; iTrack < TrackCount; iTrack++) {
|
||||
track = _tracks[iTrack];
|
||||
@@ -2111,7 +2180,7 @@ namespace CUEToolsLib
|
||||
trackPercent = (uint)(currentOffset / 0.01 / trackLength);
|
||||
double diskPercent = ((float)diskOffset) / diskLength;
|
||||
if (trackPercent != lastTrackPercent)
|
||||
statusDel(String.Format("{2} track {0:00} ({1:00}%)...", iIndex > 0 ? iTrack + 1 : iTrack, trackPercent,
|
||||
ShowProgress(String.Format("{2} track {0:00} ({1:00}%)...", iIndex > 0 ? iTrack + 1 : iTrack, trackPercent,
|
||||
noOutput ? "Verifying" : "Writing"), trackPercent, diskPercent,
|
||||
audioSource.Path, discardOutput ? null : audioDest.Path);
|
||||
lastTrackPercent = trackPercent;
|
||||
@@ -2176,7 +2245,7 @@ namespace CUEToolsLib
|
||||
}
|
||||
if (_pause)
|
||||
{
|
||||
statusDel ("Paused...", 0, 0, null, null);
|
||||
ShowProgress("Paused...", 0, 0, null, null);
|
||||
Monitor.Wait(this);
|
||||
}
|
||||
}
|
||||
@@ -2413,6 +2482,7 @@ namespace CUEToolsLib
|
||||
if (_isArchive)
|
||||
{
|
||||
RarStream IO = new RarStream(_archivePath, sourceInfo.Path);
|
||||
IO.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
|
||||
audioSource = AudioReadWrite.GetAudioSource(sourceInfo.Path, IO);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -25,12 +25,7 @@ namespace UnRarDotNet
|
||||
_pos = 0;
|
||||
_path = path;
|
||||
_fileName = fileName;
|
||||
_unrar.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
|
||||
_unrar.DataAvailable += new DataAvailableHandler(unrar_DataAvailable);
|
||||
_workThread = new Thread(Decompress);
|
||||
_workThread.Priority = ThreadPriority.BelowNormal;
|
||||
_workThread.IsBackground = true;
|
||||
_workThread.Start(null);
|
||||
_workThread = null;
|
||||
}
|
||||
public override bool CanRead
|
||||
{
|
||||
@@ -48,11 +43,14 @@ namespace UnRarDotNet
|
||||
{
|
||||
get
|
||||
{
|
||||
Go();
|
||||
lock (this)
|
||||
{
|
||||
while (_size == null && !_close)
|
||||
Monitor.Wait(this);
|
||||
}
|
||||
if (_ex != null)
|
||||
throw _ex;
|
||||
if (_size == null)
|
||||
throw new NotSupportedException();
|
||||
return _size.Value;
|
||||
@@ -93,12 +91,15 @@ namespace UnRarDotNet
|
||||
public override int Read(byte[] array, int offset, int count)
|
||||
{
|
||||
int total = 0;
|
||||
Go();
|
||||
while (count > 0)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
while (_buffer == null && !_eof)
|
||||
while (_buffer == null && !_eof && !_close)
|
||||
Monitor.Wait(this);
|
||||
if (_close)
|
||||
throw new IOException("Decompression failed", _ex);
|
||||
if (_buffer == null)
|
||||
return total;
|
||||
if (_seek_to != null)
|
||||
@@ -139,6 +140,7 @@ namespace UnRarDotNet
|
||||
}
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
Go();
|
||||
lock (this)
|
||||
{
|
||||
while (_size == null && !_close)
|
||||
@@ -181,22 +183,28 @@ namespace UnRarDotNet
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public event PasswordRequiredHandler PasswordRequired;
|
||||
public event ExtractionProgressHandler ExtractionProgress;
|
||||
|
||||
private Unrar _unrar;
|
||||
private string _fileName;
|
||||
private Thread _workThread;
|
||||
private bool _close, _rewind, _eof;
|
||||
private byte[] _buffer;
|
||||
private Exception _ex;
|
||||
int _offset, _length;
|
||||
long? _size;
|
||||
long? _seek_to;
|
||||
long _pos;
|
||||
string _path;
|
||||
|
||||
private void unrar_PasswordRequired(object sender, PasswordRequiredEventArgs e)
|
||||
private void Go()
|
||||
{
|
||||
e.Password = "PARS";
|
||||
e.ContinueOperation = true;
|
||||
if (_workThread != null) return;
|
||||
_workThread = new Thread(Decompress);
|
||||
_workThread.Priority = ThreadPriority.BelowNormal;
|
||||
_workThread.IsBackground = true;
|
||||
_workThread.Start(null);
|
||||
}
|
||||
|
||||
private void unrar_DataAvailable(object sender, DataAvailableEventArgs e)
|
||||
@@ -227,7 +235,10 @@ namespace UnRarDotNet
|
||||
|
||||
private void Decompress(object o)
|
||||
{
|
||||
//try
|
||||
_unrar.DataAvailable += new DataAvailableHandler(unrar_DataAvailable);
|
||||
_unrar.PasswordRequired += PasswordRequired;
|
||||
_unrar.ExtractionProgress += ExtractionProgress;
|
||||
try
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -264,9 +275,10 @@ namespace UnRarDotNet
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
//catch (StopExtractionException)
|
||||
//{
|
||||
//}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_ex = ex;
|
||||
}
|
||||
lock (this)
|
||||
{
|
||||
_close = true;
|
||||
|
||||
Reference in New Issue
Block a user