io refactor

master
subhra74 2022-07-26 23:49:56 +05:30
parent cad55785cd
commit 88ed950180
13 changed files with 1009 additions and 312 deletions

View File

@ -688,7 +688,7 @@ namespace XDM.Core
switch (entry.DownloadType)
{
case "Http":
var h1 = DownloadStateStore.LoadSingleSourceHTTPDownloaderState(entry.Id);
var h1 = DownloadStateIO.LoadSingleSourceHTTPDownloaderState(entry.Id);
if (h1 != null)
{
tempDir = h1.TempDir;
@ -696,7 +696,7 @@ namespace XDM.Core
}
break;
case "Dash":
var h2 = DownloadStateStore.LoadDualSourceHTTPDownloaderState(entry.Id);
var h2 = DownloadStateIO.LoadDualSourceHTTPDownloaderState(entry.Id);
if (h2 != null)
{
tempDir = h2.TempDir;
@ -704,7 +704,7 @@ namespace XDM.Core
}
break;
case "Hls":
var hls = DownloadStateStore.LoadMultiSourceHLSDownloadState(entry.Id);
var hls = DownloadStateIO.LoadMultiSourceHLSDownloadState(entry.Id);
if (hls != null)
{
tempDir = hls.TempDirectory;
@ -712,7 +712,7 @@ namespace XDM.Core
}
break;
case "Mpd-Dash":
var dash = DownloadStateStore.LoadMultiSourceDASHDownloadState(entry.Id);
var dash = DownloadStateIO.LoadMultiSourceDASHDownloadState(entry.Id);
if (dash != null)
{
tempDir = dash.TempDirectory;

View File

@ -233,7 +233,7 @@ namespace XDM.Core
{
using var ms = new MemoryStream(bytes);
using var reader = new BinaryReader(ms);
SerializationHelper.DeserializeConfig(instance, reader);
ConfigIO.DeserializeConfig(instance, reader);
}
}
catch (Exception ex)
@ -385,7 +385,7 @@ namespace XDM.Core
public static void SaveConfig()
{
SerializationHelper.SerializeConfig();
ConfigIO.SerializeConfig();
}
//public static void SaveConfig3()

View File

@ -158,7 +158,7 @@ namespace XDM.Core.Downloader.Adaptive.Dash
protected override void RestoreState()
{
var state = DownloadStateStore.LoadMultiSourceDASHDownloadState(Id!);
var state = DownloadStateIO.LoadMultiSourceDASHDownloadState(Id!);
this._state = state;
//var bytes = TransactedIO.ReadBytes(Id + ".state", Config.DataDir);
@ -241,7 +241,7 @@ namespace XDM.Core.Downloader.Adaptive.Dash
protected override void SaveState()
{
DownloadStateStore.Save((MultiSourceDASHDownloadState)_state);
DownloadStateIO.Save((MultiSourceDASHDownloadState)_state);
//TransactedIO.WriteBytes(DownloadStateStore.Save((MultiSourceDASHDownloadState)_state), Id + ".state", Config.DataDir);
//TransactedIO.Write(JsonConvert.SerializeObject(_state as MultiSourceDASHDownloadState),
// Id + ".state", Config.DataDir);

View File

@ -360,7 +360,7 @@ namespace XDM.Core.Downloader.Adaptive.Hls
protected override void RestoreState()
{
var state = DownloadStateStore.LoadMultiSourceHLSDownloadState(Id!);
var state = DownloadStateIO.LoadMultiSourceHLSDownloadState(Id!);
this._state = state;
//var bytes = TransactedIO.ReadBytes(Id + ".state", Config.DataDir);
@ -434,7 +434,7 @@ namespace XDM.Core.Downloader.Adaptive.Hls
protected override void SaveState()
{
DownloadStateStore.Save((MultiSourceHLSDownloadState)this._state);
DownloadStateIO.Save((MultiSourceHLSDownloadState)this._state);
//TransactedIO.WriteBytes(DownloadStateStore.Save((MultiSourceHLSDownloadState)this._state), Id + ".state", Config.DataDir);
//((TransactedIO.Write(JsonConvert.SerializeObject(_state as MultiSourceHLSDownloadState), Id + ".state", Config.DataDir);
//File.WriteAllText(Path.Combine(Config.DataDir, Id + ".state"), JsonConvert.SerializeObject(_state as MultiSourceHLSDownloadState));

View File

@ -311,12 +311,12 @@ namespace XDM.Core.Downloader.Progressive.DualHttp
protected override void SaveState()
{
DownloadStateStore.Save(state);// TransactedIO.WriteBytes(DownloadStateStore.Save(state), Id + ".state", Config.DataDir);
DownloadStateIO.Save(state);// TransactedIO.WriteBytes(DownloadStateStore.Save(state), Id + ".state", Config.DataDir);
}
public override void RestoreState()
{
state = DownloadStateStore.LoadDualSourceHTTPDownloaderState(Id!);
state = DownloadStateIO.LoadDualSourceHTTPDownloaderState(Id!);
//var bytes = TransactedIO.ReadBytes(Id + ".state", Config.DataDir);
//if (bytes == null)
//{

View File

@ -168,14 +168,14 @@ namespace XDM.Core.Downloader.Progressive.SingleHttp
protected override void SaveState()
{
DownloadStateStore.Save(state!);
DownloadStateIO.Save(state!);
//TransactedIO.WriteStream(Id + ".state", Config.DataDir, s => DownloadStateStore.StateToBytes(state!, s));
//TransactedIO.WriteBytes(DownloadStateStore.StateToBytes(state), Id + ".state", Config.DataDir);
}
public override void RestoreState()
{
state = DownloadStateStore.LoadSingleSourceHTTPDownloaderState(Id!);
state = DownloadStateIO.LoadSingleSourceHTTPDownloaderState(Id!);
//if (!TransactedIO.ReadStream(Id + ".state", Config.DataDir, s =>
//{
// state = DownloadStateStore.SingleSourceHTTPDownloaderStateFromBytes(s);

View File

@ -0,0 +1,476 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using TraceLog;
using XDM.Core;
using XDM.Core.Downloader;
namespace XDM.Core.IO
{
internal static class ConfigIO
{
public const byte INT = 0, STRING = 1, BOOL = 2, STRING_ARRAY = 3, INT_ARRAY = 4, OBJECT_ARRAY = 5, LONG = 6, OBJECT = 7;
public static void SkipUnknownField(byte type, string name, BinaryReader r)
{
Log.Debug($"Config skipping unknown field '{name}' of type '{type}'");
switch (type)
{
case INT:
r.ReadInt32();
break;
case LONG:
r.ReadInt64();
break;
case STRING:
r.ReadString();
break;
case BOOL:
r.ReadBoolean();
break;
case STRING_ARRAY:
var sc = r.ReadInt16();
for (int i = 0; i < sc; i++)
{
r.ReadString();
}
break;
case INT_ARRAY:
var ic = r.ReadInt16();
for (int i = 0; i < ic; i++)
{
r.ReadInt32();
}
break;
case OBJECT_ARRAY:
var oc = r.ReadInt16();
var fc = r.ReadInt16();
for (int i = 0; i < oc; i++)
{
for (int j = 0; j < fc; j++)
{
var name1 = r.ReadString();
var type1 = r.ReadByte();
SkipUnknownField(type1, name1, r);
}
}
break;
case OBJECT:
var fc1 = r.ReadInt16();
for (int j = 0; j < fc1; j++)
{
var name1 = r.ReadString();
var type1 = r.ReadByte();
SkipUnknownField(type1, name1, r);
}
break;
default:
throw new IOException($"Unknown field type '{type}'");
}
}
public static void DeserializeConfig(Config instance, BinaryReader r)
{
var fieldsCount = r.ReadInt16();
for (var i = 0; i < fieldsCount; i++)
{
var fieldName = r.ReadString();
var fieldType = r.ReadByte();
switch (fieldName)
{
case "AfterCompletionCommand":
instance.AfterCompletionCommand = r.ReadString();
break;
case "UserSelectedDownloadFolder":
instance.UserSelectedDownloadFolder = r.ReadString();
break;
case "AntiVirusArgs":
instance.AntiVirusArgs = r.ReadString();
break;
case "AntiVirusExecutable":
instance.AntiVirusExecutable = r.ReadString();
break;
case "BlockedHosts":
var blockedHostsLength = r.ReadInt16();
instance.BlockedHosts = new string[blockedHostsLength];
for (int a = 0; a < blockedHostsLength; a++)
{
instance.BlockedHosts[a] = r.ReadString();
}
break;
case "Categories":
var categoriesLength = r.ReadInt16();
var categoriesFieldCount = r.ReadInt16();
var categories = new List<Category>(categoriesLength);
for (int a = 0; a < categoriesLength; a++)
{
var cat = new Category();
for (int b = 0; b < categoriesFieldCount; b++)
{
var fieldName1 = r.ReadString();
var fieldType1 = r.ReadByte();
switch (fieldName1)
{
case "DefaultFolder":
cat.DefaultFolder = r.ReadString();
break;
case "DisplayName":
cat.DisplayName = r.ReadString();
break;
case "IsPredefined":
cat.IsPredefined = r.ReadBoolean();
break;
case "Name":
cat.Name = r.ReadString();
break;
case "FileExtensions":
cat.FileExtensions = new HashSet<string>();
var fileExtensionsLength1 = r.ReadInt16();
for (int m = 0; m < fileExtensionsLength1; m++)
{
cat.FileExtensions.Add(r.ReadString());
}
break;
default:
SkipUnknownField(fieldType1, fieldName1, r);
break;
}
}
categories.Add(cat);
instance.Categories = categories;
}
break;
case "DefaultDownloadFolder":
instance.DefaultDownloadFolder = r.ReadString();
break;
case "EnableSpeedLimit":
instance.EnableSpeedLimit = r.ReadBoolean();
break;
case "FetchServerTimeStamp":
instance.FetchServerTimeStamp = r.ReadBoolean();
break;
case "FileConflictResolution":
instance.FileConflictResolution = (FileConflictResolution)r.ReadInt32();
break;
case "FolderSelectionMode":
instance.FolderSelectionMode = (FolderSelectionMode)r.ReadInt32();
break;
case "DefaltDownloadSpeed":
instance.DefaltDownloadSpeed = r.ReadInt32();
break;
case "IsBrowserMonitoringEnabled":
instance.IsBrowserMonitoringEnabled = r.ReadBoolean();
break;
case "KeepPCAwake":
instance.KeepPCAwake = r.ReadBoolean();
break;
case "Language":
instance.Language = r.ReadString();
break;
case "MaxParallelDownloads":
instance.MaxParallelDownloads = r.ReadInt32();
break;
case "MaxRetry":
instance.MaxRetry = r.ReadInt32();
break;
case "MaxSegments":
instance.MaxSegments = r.ReadInt32();
break;
case "MinVideoSize":
instance.MinVideoSize = r.ReadInt32();
break;
case "MonitorClipboard":
instance.MonitorClipboard = r.ReadBoolean();
break;
case "NetworkTimeout":
instance.NetworkTimeout = r.ReadInt32();
break;
case "RetryDelay":
instance.RetryDelay = r.ReadInt32();
break;
case "RunCommandAfterCompletion":
instance.RunCommandAfterCompletion = r.ReadBoolean();
break;
//case "RunOnLogon":
// instance.RunOnLogon = r.ReadBoolean();
// break;
case "ScanWithAntiVirus":
instance.ScanWithAntiVirus = r.ReadBoolean();
break;
case "ShowDownloadCompleteWindow":
instance.ShowDownloadCompleteWindow = r.ReadBoolean();
break;
case "ShowProgressWindow":
instance.ShowProgressWindow = r.ReadBoolean();
break;
case "ShutdownAfterAllFinished":
instance.ShutdownAfterAllFinished = r.ReadBoolean();
break;
case "StartDownloadAutomatically":
instance.StartDownloadAutomatically = r.ReadBoolean();
break;
case "TempDir":
instance.TempDir = r.ReadString();
break;
case "AllowSystemDarkTheme":
instance.AllowSystemDarkTheme = r.ReadBoolean();
break;
case "DoubleClickOpenFile":
instance.DoubleClickOpenFile = r.ReadBoolean();
break;
case "FileExtensions":
var fileExtensionsLength = r.ReadInt16();
instance.FileExtensions = new string[fileExtensionsLength];
for (int a = 0; a < fileExtensionsLength; a++)
{
instance.FileExtensions[a] = r.ReadString();
}
break;
case "RecentFolders":
var recentFoldersLength = r.ReadInt16();
instance.RecentFolders = new List<string>(recentFoldersLength);
for (int a = 0; a < recentFoldersLength; a++)
{
instance.RecentFolders.Add(r.ReadString());
}
break;
case "VideoExtensions":
var videoExtensionsLength = r.ReadInt16();
instance.VideoExtensions = new string[videoExtensionsLength];
for (int a = 0; a < videoExtensionsLength; a++)
{
instance.VideoExtensions[a] = r.ReadString();
}
break;
case "UserCredentials":
var userCredentialsLength = r.ReadInt16();
var passwordEntryFieldLength = r.ReadInt16();
var passwordEntries = new List<PasswordEntry>(userCredentialsLength);
for (int a = 0; a < userCredentialsLength; a++)
{
var passwordEntry = new PasswordEntry();
for (int b = 0; b < passwordEntryFieldLength; b++)
{
var fieldName1 = r.ReadString();
var fieldType1 = r.ReadByte();
switch (fieldName1)
{
case "Host":
passwordEntry.Host = r.ReadString();
break;
case "User":
passwordEntry.User = r.ReadString();
break;
case "Password":
passwordEntry.Password = r.ReadString();
break;
default:
SkipUnknownField(fieldType1, fieldName1, r);
break;
}
}
passwordEntries.Add(passwordEntry);
instance.UserCredentials = passwordEntries;
}
break;
case "Proxy":
instance.Proxy = ProxyInfoSerializer.Deserialize(r);
break;
default:
SkipUnknownField(fieldType, fieldName, r);
break;
}
}
}
private static void WriteString(BinaryWriter w, string value, string name)
{
w.Write(name);
w.Write(STRING);
w.Write(value ?? string.Empty);
}
private static void WriteBoolean(BinaryWriter w, bool value, string name)
{
w.Write(name);
w.Write(BOOL);
w.Write(value);
}
private static void WriteInt32(BinaryWriter w, int value, string name)
{
w.Write(name);
w.Write(INT);
w.Write(value);
}
private static void WriteInt64(BinaryWriter w, long value, string name)
{
w.Write(name);
w.Write(LONG);
w.Write(value);
}
private static void WriteStringArray(BinaryWriter w, IEnumerable<string> array, string name, int count)
{
w.Write(name);
w.Write(STRING_ARRAY);
w.Write((short)count);
foreach (var item in array)
{
w.Write(item);
}
}
public static void SerializeConfig()
{
var instance = Config.Instance;
using var ms = new MemoryStream();
using var w = new BinaryWriter(ms);
w.Write((short)(instance.Proxy.HasValue ? 36 : 35)); //total fields
WriteString(w, instance.AfterCompletionCommand, "AfterCompletionCommand");
WriteString(w, instance.UserSelectedDownloadFolder, "UserSelectedDownloadFolder");
WriteString(w, instance.AntiVirusArgs, "AntiVirusArgs");
WriteString(w, instance.AntiVirusExecutable, "AntiVirusExecutable");
WriteString(w, instance.DefaultDownloadFolder, "DefaultDownloadFolder");
WriteString(w, instance.Language, "Language");
WriteString(w, instance.TempDir, "TempDir");
WriteBoolean(w, instance.EnableSpeedLimit, "EnableSpeedLimit");
WriteBoolean(w, instance.FetchServerTimeStamp, "FetchServerTimeStamp");
WriteBoolean(w, instance.IsBrowserMonitoringEnabled, "IsBrowserMonitoringEnabled");
WriteBoolean(w, instance.KeepPCAwake, "KeepPCAwake");
WriteBoolean(w, instance.MonitorClipboard, "MonitorClipboard");
WriteBoolean(w, instance.RunCommandAfterCompletion, "RunCommandAfterCompletion");
//WriteBoolean(w, instance.RunOnLogon, "RunOnLogon");
WriteBoolean(w, instance.ScanWithAntiVirus, "ScanWithAntiVirus");
WriteBoolean(w, instance.ShowDownloadCompleteWindow, "ShowDownloadCompleteWindow");
WriteBoolean(w, instance.ShowProgressWindow, "ShowProgressWindow");
WriteBoolean(w, instance.ShutdownAfterAllFinished, "ShutdownAfterAllFinished");
WriteBoolean(w, instance.StartDownloadAutomatically, "StartDownloadAutomatically");
WriteBoolean(w, instance.AllowSystemDarkTheme, "AllowSystemDarkTheme");
WriteBoolean(w, instance.DoubleClickOpenFile, "DoubleClickOpenFile");
WriteInt32(w, (int)instance.FileConflictResolution, "FileConflictResolution");
WriteInt32(w, (int)instance.FolderSelectionMode, "FolderSelectionMode");
WriteInt32(w, instance.DefaltDownloadSpeed, "DefaltDownloadSpeed");
WriteInt32(w, instance.MaxParallelDownloads, "MaxParallelDownloads");
WriteInt32(w, instance.MaxRetry, "MaxRetry");
WriteInt32(w, instance.MaxSegments, "MaxSegments");
WriteInt32(w, instance.MinVideoSize, "MinVideoSize");
WriteInt32(w, instance.NetworkTimeout, "NetworkTimeout");
WriteInt32(w, instance.RetryDelay, "RetryDelay");
WriteStringArray(w, instance.BlockedHosts, "BlockedHosts", instance.BlockedHosts.Length);
WriteStringArray(w, instance.FileExtensions, "FileExtensions", instance.FileExtensions.Length);
WriteStringArray(w, instance.RecentFolders, "RecentFolders", instance.RecentFolders.Count);
WriteStringArray(w, instance.VideoExtensions, "VideoExtensions", instance.VideoExtensions.Length);
w.Write("Categories");
w.Write(OBJECT_ARRAY);
w.Write((short)instance.Categories.Count());
w.Write((short)5); //no of fields in Category class
foreach (var cat in instance.Categories)
{
WriteString(w, cat.DefaultFolder, "DefaultFolder");
WriteString(w, cat.DisplayName, "DisplayName");
WriteBoolean(w, cat.IsPredefined, "IsPredefined");
WriteString(w, cat.Name, "Name");
WriteStringArray(w, cat.FileExtensions, "FileExtensions", cat.FileExtensions.Count);
}
w.Write("UserCredentials");
w.Write(OBJECT_ARRAY);
w.Write((short)instance.UserCredentials.Count());
w.Write((short)3); //no of fields in Category class
foreach (var pe in instance.UserCredentials)
{
WriteString(w, pe.Host, "Host");
WriteString(w, pe.User, "User");
WriteString(w, pe.Password, "Password");
}
if (instance.Proxy.HasValue)
{
ProxyInfoSerializer.Serialize(instance.Proxy.Value, w);
}
w.Close();
ms.Close();
TransactedIO.WriteBytes(ms.ToArray(), "settings.dat", Config.DataDir);
}
public static void SerializeProxyInfo(ProxyInfo proxy, BinaryWriter w)
{
w.Write("Proxy");
w.Write(OBJECT);
w.Write((short)5);
w.Write(nameof(proxy.Host));
w.Write(STRING);
w.Write(proxy.Host);
w.Write(nameof(proxy.Port));
w.Write(INT);
w.Write(proxy.Port);
w.Write(nameof(proxy.ProxyType));
w.Write(INT);
w.Write((int)proxy.ProxyType);
w.Write(nameof(proxy.UserName));
w.Write(STRING);
w.Write(proxy.UserName);
w.Write(nameof(proxy.Password));
w.Write(STRING);
w.Write(proxy.Password ?? string.Empty);
}
public static ProxyInfo DeserializeProxyInfo(BinaryReader r)
{
var proxy = new ProxyInfo();
var fieldCount = r.ReadInt16();
for (int i = 0; i < fieldCount; i++)
{
var fieldName = r.ReadString();
var fieldType = r.ReadByte();
switch (fieldName)
{
case "Host":
proxy.Host = r.ReadString();
break;
case "Port":
proxy.Port = r.ReadInt32();
break;
case "ProxyType":
proxy.ProxyType = (ProxyType)r.ReadInt32();
break;
case "UserName":
proxy.UserName = r.ReadString();
break;
case "Password":
proxy.Password = r.ReadString();
break;
default:
switch (fieldType)
{
case INT:
r.ReadInt32();
break;
case STRING:
r.ReadString();
break;
case BOOL:
r.ReadBoolean();
break;
default:
throw new IOException($"Unsupported type: '{fieldType}'");
}
break;
}
}
return proxy;
}
}
}

View File

@ -0,0 +1,508 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using XDM.Core;
using XDM.Core.Downloader.Adaptive.Dash;
using XDM.Core.Downloader.Adaptive.Hls;
using XDM.Core.Downloader.Progressive.DualHttp;
using XDM.Core.Downloader.Progressive.SingleHttp;
using XDM.Core.Util;
using XDM.Messaging;
#if NET35
using XDM.Compatibility;
#endif
namespace XDM.Core.IO
{
delegate void BinaryReaderStreamConsumer(BinaryReader r);
delegate void BinaryWriterStreamConsumer(BinaryWriter w);
internal static class TransactedBinaryDataReader
{
public static void Read(string file, string folder, BinaryReaderStreamConsumer callback)
{
if (!TransactedIO.ReadStream(file, folder, stream =>
{
#if NET35
using var ms = new MemoryStream();
stream.CopyTo(ms);
using var r = new BinaryReader(ms);
callback(r);
#else
using var r = new BinaryReader(stream, Encoding.UTF8, true);
callback(r);
#endif
}))
{
throw new IOException(Path.Combine(Config.DataDir, file));
}
}
public static void Write(string file, string folder, BinaryWriterStreamConsumer callback)
{
TransactedIO.WriteStream(file, folder, stream =>
{
#if NET35
using var ms = new MemoryStream();
using var w = new BinaryWriter(ms);
#else
using var w = new BinaryWriter(stream, Encoding.UTF8, true);
#endif
callback(w);
#if NET35
ms.CopyTo(stream);
#endif
});
}
}
public static class DownloadStateIO
{
public static SingleSourceHTTPDownloaderState LoadSingleSourceHTTPDownloaderState(string id)
{
SingleSourceHTTPDownloaderState? state = null;
TransactedBinaryDataReader.Read($"{id}.state", Config.DataDir, r =>
{
state = SingleSourceHTTPDownloaderStateFromBytes(r);
});
if (state == null)
{
throw new IOException("Unable to read state: " + id);
}
return state;
}
private static SingleSourceHTTPDownloaderState SingleSourceHTTPDownloaderStateFromBytes(BinaryReader r)
{
var state = new SingleSourceHTTPDownloaderState
{
Id = r.ReadString(),
TempDir = XDM.Messaging.StreamHelper.ReadString(r),
FileSize = r.ReadInt64(),
LastModified = DateTime.FromBinary(r.ReadInt64()),
SpeedLimit = r.ReadInt32(),
Url = new Uri(r.ReadString())
};
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateHeaders(r, out Dictionary<string, List<string>> headers);
state.Headers = headers;
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateCookies(r, out Dictionary<string, string> cookies);
state.Cookies = cookies;
}
if (r.ReadBoolean())
{
state.Proxy = new ProxyInfo
{
Host = XDM.Messaging.StreamHelper.ReadString(r),
Port = r.ReadInt32(),
ProxyType = (ProxyType)r.ReadInt32(),
UserName = XDM.Messaging.StreamHelper.ReadString(r),
Password = XDM.Messaging.StreamHelper.ReadString(r),
};
}
state.ConvertToMp3 = r.ReadBoolean();
return state;
}
public static void Save(SingleSourceHTTPDownloaderState state)
{
TransactedBinaryDataReader.Write($"{state.Id}.state", Config.DataDir, w => StateToBytes(state, w));
}
private static void StateToBytes(SingleSourceHTTPDownloaderState state, BinaryWriter w)
{
w.Write(state!.Id!);
w.Write(state.TempDir ?? string.Empty);
w.Write(state.FileSize);
w.Write(state.LastModified.ToBinary());
w.Write(state.SpeedLimit);
w.Write(state.Url.ToString());
var hasHeaders = state.Headers != null;
w.Write(hasHeaders);
if (hasHeaders)
{
XDM.Messaging.StreamHelper.WriteStateHeaders(state.Headers, w);
}
var hasCookies = state.Cookies != null;
w.Write(hasCookies);
if (hasCookies)
{
XDM.Messaging.StreamHelper.WriteStateCookies(state.Cookies, w);
}
var hasProxy = state.Proxy.HasValue;
w.Write(hasProxy);
if (hasProxy)
{
w.Write(state.Proxy!.Value.Host ?? string.Empty);
w.Write(state.Proxy!.Value.Port);
w.Write((int)state.Proxy!.Value.ProxyType);
w.Write(state.Proxy!.Value.UserName ?? string.Empty);
w.Write(state.Proxy!.Value.Password ?? string.Empty);
}
w.Write(state.ConvertToMp3);
}
public static DualSourceHTTPDownloaderState LoadDualSourceHTTPDownloaderState(string id)
{
DualSourceHTTPDownloaderState? state = null;
TransactedBinaryDataReader.Read($"{id}.state", Config.DataDir, r =>
{
state = DualSourceHTTPDownloaderStateFromBytes(r);
});
if (state == null)
{
throw new IOException("Unable to read state: " + id);
}
return state;
}
private static DualSourceHTTPDownloaderState DualSourceHTTPDownloaderStateFromBytes(BinaryReader r)
{
var state = new DualSourceHTTPDownloaderState
{
Id = r.ReadString(),
TempDir = XDM.Messaging.StreamHelper.ReadString(r),
FileSize = r.ReadInt64(),
LastModified = DateTime.FromBinary(r.ReadInt64()),
SpeedLimit = r.ReadInt32(),
Init1 = r.ReadBoolean(),
Init2 = r.ReadBoolean(),
Url1 = new Uri(r.ReadString()),
Url2 = new Uri(r.ReadString()),
};
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateHeaders(r, out Dictionary<string, List<string>> headers);
state.Headers1 = headers;
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateHeaders(r, out Dictionary<string, List<string>> headers);
state.Headers2 = headers;
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateCookies(r, out Dictionary<string, string> cookies);
state.Cookies1 = cookies;
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateCookies(r, out Dictionary<string, string> cookies);
state.Cookies2 = cookies;
}
if (r.ReadBoolean())
{
state.Proxy = new ProxyInfo
{
Host = XDM.Messaging.StreamHelper.ReadString(r),
Port = r.ReadInt32(),
ProxyType = (ProxyType)r.ReadInt32(),
UserName = XDM.Messaging.StreamHelper.ReadString(r),
Password = XDM.Messaging.StreamHelper.ReadString(r),
};
}
return state;
}
public static void Save(DualSourceHTTPDownloaderState state)
{
TransactedBinaryDataReader.Write($"{state.Id}.state", Config.DataDir, w => StateToBytes(state, w));
}
private static void StateToBytes(DualSourceHTTPDownloaderState state, BinaryWriter w)
{
w.Write(state.Id!);
w.Write(state.TempDir ?? string.Empty);
w.Write(state.FileSize);
w.Write(state.LastModified.ToBinary());
w.Write(state.SpeedLimit);
w.Write(state.Init1);
w.Write(state.Init2);
w.Write(state.Url1.ToString());
w.Write(state.Url2.ToString());
var hasHeaders1 = state.Headers1 != null;
w.Write(hasHeaders1);
if (hasHeaders1)
{
XDM.Messaging.StreamHelper.WriteStateHeaders(state.Headers1, w);
}
var hasHeaders2 = state.Headers2 != null;
w.Write(hasHeaders2);
if (hasHeaders2)
{
XDM.Messaging.StreamHelper.WriteStateHeaders(state.Headers2, w);
}
var hasCookies1 = state.Cookies1 != null;
w.Write(hasCookies1);
if (hasCookies1)
{
XDM.Messaging.StreamHelper.WriteStateCookies(state.Cookies1, w);
}
var hasCookies2 = state.Cookies2 != null;
w.Write(hasCookies2);
if (hasCookies2)
{
XDM.Messaging.StreamHelper.WriteStateCookies(state.Cookies2, w);
}
var hasProxy = state.Proxy.HasValue;
w.Write(hasProxy);
if (hasProxy)
{
w.Write(state.Proxy!.Value.Host ?? string.Empty);
w.Write(state.Proxy!.Value.Port);
w.Write((int)state.Proxy!.Value.ProxyType);
w.Write(state.Proxy!.Value.UserName ?? string.Empty);
w.Write(state.Proxy!.Value.Password ?? string.Empty);
}
}
public static void Save(MultiSourceDASHDownloadState state)
{
TransactedBinaryDataReader.Write($"{state.Id}.state", Config.DataDir, w => StateToBytes(state, w));
}
private static void StateToBytes(MultiSourceDASHDownloadState state, BinaryWriter w)
{
w.Write(state.Id);
w.Write(state.TempDirectory ?? string.Empty);
w.Write(state.FileSize);
w.Write(state.Demuxed);
w.Write(state.SpeedLimit);
w.Write(state.AudioChunkCount);
w.Write(state.AudioContainerFormat ?? string.Empty);
w.Write(state.VideoChunkCount);
w.Write(state.VideoContainerFormat ?? string.Empty);
w.Write(state.Duration);
w.Write(state.Url ?? string.Empty);
w.Write(state.AudioSegments?.Count ?? 0);
for (var i = 0; i < (state.AudioSegments?.Count ?? 0); i++)
{
w.Write(state.AudioSegments![i].ToString());
}
w.Write(state.VideoSegments?.Count ?? 0);
for (var i = 0; i < (state.VideoSegments?.Count ?? 0); i++)
{
w.Write(state.VideoSegments![i].ToString());
}
var hasHeaders = state.Headers != null;
w.Write(hasHeaders);
if (hasHeaders)
{
XDM.Messaging.StreamHelper.WriteStateHeaders(state.Headers, w);
}
var hasCookies = state.Cookies != null;
w.Write(hasCookies);
if (hasCookies)
{
XDM.Messaging.StreamHelper.WriteStateCookies(state.Cookies, w);
}
var hasProxy = state.Proxy.HasValue;
w.Write(hasProxy);
if (hasProxy)
{
w.Write(state.Proxy!.Value.Host ?? string.Empty);
w.Write(state.Proxy!.Value.Port);
w.Write((int)state.Proxy!.Value.ProxyType);
w.Write(state.Proxy!.Value.UserName ?? string.Empty);
w.Write(state.Proxy!.Value.Password ?? string.Empty);
}
}
public static MultiSourceDASHDownloadState LoadMultiSourceDASHDownloadState(string id)
{
MultiSourceDASHDownloadState? state = null;
TransactedBinaryDataReader.Read($"{id}.state", Config.DataDir, r =>
{
state = MultiSourceDASHDownloadStateFromBytes(r);
});
if (state == null)
{
throw new IOException("Unable to read state: " + id);
}
return state;
}
private static MultiSourceDASHDownloadState MultiSourceDASHDownloadStateFromBytes(BinaryReader r)
{
var state = new MultiSourceDASHDownloadState
{
Id = r.ReadString(),
TempDirectory = XDM.Messaging.StreamHelper.ReadString(r),
FileSize = r.ReadInt64(),
Demuxed = r.ReadBoolean(),
SpeedLimit = r.ReadInt32(),
AudioChunkCount = r.ReadInt32(),
AudioContainerFormat = XDM.Messaging.StreamHelper.ReadString(r),
VideoChunkCount = r.ReadInt32(),
VideoContainerFormat = XDM.Messaging.StreamHelper.ReadString(r),
Duration = r.ReadDouble(),
Url = XDM.Messaging.StreamHelper.ReadString(r)
};
var ac = r.ReadInt32();
if (ac != 0)
{
state.AudioSegments = new(ac);
for (var i = 0; i < ac; i++)
{
state.AudioSegments.Add(new Uri(r.ReadString()));
}
}
var vc = r.ReadInt32();
if (vc != 0)
{
state.VideoSegments = new(vc);
for (var i = 0; i < vc; i++)
{
state.VideoSegments.Add(new Uri(r.ReadString()));
}
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateHeaders(r, out Dictionary<string, List<string>> headers);
state.Headers = headers;
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateCookies(r, out Dictionary<string, string> cookies);
state.Cookies = cookies;
}
if (r.ReadBoolean())
{
state.Proxy = new ProxyInfo
{
Host = XDM.Messaging.StreamHelper.ReadString(r),
Port = r.ReadInt32(),
ProxyType = (ProxyType)r.ReadInt32(),
UserName = XDM.Messaging.StreamHelper.ReadString(r),
Password = XDM.Messaging.StreamHelper.ReadString(r),
};
}
return state;
}
public static void Save(MultiSourceHLSDownloadState state)
{
TransactedBinaryDataReader.Write($"{state.Id}.state", Config.DataDir, w => StateToBytes(state, w));
}
private static void StateToBytes(MultiSourceHLSDownloadState state, BinaryWriter w)
{
w.Write(state.Id);
w.Write(state.TempDirectory ?? string.Empty);
w.Write(state.FileSize);
w.Write(state.Demuxed);
w.Write(state.SpeedLimit);
w.Write(state.AudioChunkCount);
w.Write(state.AudioContainerFormat ?? string.Empty);
w.Write(state.VideoChunkCount);
w.Write(state.VideoContainerFormat ?? string.Empty);
w.Write(state.Duration);
w.Write(state.MuxedPlaylistUrl?.ToString() ?? string.Empty);
w.Write(state.NonMuxedAudioPlaylistUrl?.ToString() ?? string.Empty);
w.Write(state.NonMuxedVideoPlaylistUrl?.ToString() ?? string.Empty);
var hasHeaders = state.Headers != null;
w.Write(hasHeaders);
if (hasHeaders)
{
XDM.Messaging.StreamHelper.WriteStateHeaders(state.Headers, w);
}
var hasCookies = state.Cookies != null;
w.Write(hasCookies);
if (hasCookies)
{
XDM.Messaging.StreamHelper.WriteStateCookies(state.Cookies, w);
}
var hasProxy = state.Proxy.HasValue;
w.Write(hasProxy);
if (hasProxy)
{
w.Write(state.Proxy!.Value.Host ?? string.Empty);
w.Write(state.Proxy!.Value.Port);
w.Write((int)state.Proxy!.Value.ProxyType);
w.Write(state.Proxy!.Value.UserName ?? string.Empty);
w.Write(state.Proxy!.Value.Password ?? string.Empty);
}
}
public static MultiSourceHLSDownloadState LoadMultiSourceHLSDownloadState(string id)
{
MultiSourceHLSDownloadState? state = null;
TransactedBinaryDataReader.Read($"{id}.state", Config.DataDir, r =>
{
state = MultiSourceHLSDownloadStateFromBytes(r);
});
if (state == null)
{
throw new IOException("Unable to read state: " + id);
}
return state;
}
private static MultiSourceHLSDownloadState MultiSourceHLSDownloadStateFromBytes(BinaryReader r)
{
var state = new MultiSourceHLSDownloadState
{
Id = r.ReadString(),
TempDirectory = XDM.Messaging.StreamHelper.ReadString(r),
FileSize = r.ReadInt64(),
Demuxed = r.ReadBoolean(),
SpeedLimit = r.ReadInt32(),
AudioChunkCount = r.ReadInt32(),
AudioContainerFormat = XDM.Messaging.StreamHelper.ReadString(r),
VideoChunkCount = r.ReadInt32(),
VideoContainerFormat = XDM.Messaging.StreamHelper.ReadString(r),
Duration = r.ReadDouble()
};
var muxedPlaylistUrl = XDM.Messaging.StreamHelper.ReadString(r);
var nonMuxedAudioPlaylistUrl = XDM.Messaging.StreamHelper.ReadString(r);
var nonMuxedVideoPlaylistUrl = XDM.Messaging.StreamHelper.ReadString(r);
if (muxedPlaylistUrl != null)
{
state.MuxedPlaylistUrl = new Uri(muxedPlaylistUrl);
}
if (nonMuxedAudioPlaylistUrl != null)
{
state.NonMuxedAudioPlaylistUrl = new Uri(nonMuxedAudioPlaylistUrl);
}
if (nonMuxedVideoPlaylistUrl != null)
{
state.NonMuxedVideoPlaylistUrl = new Uri(nonMuxedVideoPlaylistUrl);
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateHeaders(r, out Dictionary<string, List<string>> headers);
state.Headers = headers;
}
if (r.ReadBoolean())
{
XDM.Messaging.StreamHelper.ReadStateCookies(r, out Dictionary<string, string> cookies);
state.Cookies = cookies;
}
if (r.ReadBoolean())
{
state.Proxy = new ProxyInfo
{
Host = XDM.Messaging.StreamHelper.ReadString(r),
Port = r.ReadInt32(),
ProxyType = (ProxyType)r.ReadInt32(),
UserName = XDM.Messaging.StreamHelper.ReadString(r),
Password = XDM.Messaging.StreamHelper.ReadString(r),
};
}
return state;
}
}
}

View File

@ -9,7 +9,7 @@ using XDM.Core.Downloader;
namespace XDM.Core.IO
{
internal static class SerializationHelper
internal static class ConfigIO
{
public const byte INT = 0, STRING = 1, BOOL = 2, STRING_ARRAY = 3, INT_ARRAY = 4, OBJECT_ARRAY = 5, LONG = 6, OBJECT = 7;
@ -472,292 +472,5 @@ namespace XDM.Core.IO
}
return proxy;
}
public static List<InProgressDownloadEntry> DeserializeInProgressDownloadEntry(BinaryReader r)
{
var count = r.ReadInt32();
var list = new List<InProgressDownloadEntry>(count);
for (int i = 0; i < count; i++)
{
var instance = new InProgressDownloadEntry();
var fieldsCount = r.ReadInt16();
for (var j = 0; j < fieldsCount; j++)
{
var fieldName = r.ReadString();
var fieldType = r.ReadByte();
switch (fieldName)
{
case "Id":
instance.Id = r.ReadString();
break;
case "Name":
instance.Name = r.ReadString();
break;
case "DateAdded":
instance.DateAdded = DateTime.FromBinary(r.ReadInt64());
break;
case "DownloadType":
instance.DownloadType = r.ReadString();
break;
case "FileNameFetchMode":
instance.FileNameFetchMode = (FileNameFetchMode)r.ReadInt32();
break;
case "MaxSpeedLimitInKiB":
instance.MaxSpeedLimitInKiB = r.ReadInt32();
break;
case "Progress":
instance.Progress = r.ReadInt32();
break;
case "Size":
instance.Size = r.ReadInt64();
break;
case "PrimaryUrl":
instance.PrimaryUrl = r.ReadString();
break;
case "TargetDir":
instance.TargetDir = r.ReadString();
break;
case "RefererUrl":
instance.RefererUrl = r.ReadString();
break;
case "Authentication":
var authenticationInfoFieldLength = r.ReadInt16();
var authenticationInfo = new AuthenticationInfo();
for (int b = 0; b < authenticationInfoFieldLength; b++)
{
var fieldName1 = r.ReadString();
var fieldType1 = r.ReadByte();
switch (fieldName1)
{
case "User":
authenticationInfo.UserName = r.ReadString();
break;
case "Password":
authenticationInfo.Password = r.ReadString();
break;
default:
SkipUnknownField(fieldType1, fieldName1, r);
break;
}
}
break;
case "Proxy":
instance.Proxy = DeserializeProxyInfo(r);
break;
default:
SkipUnknownField(fieldType, fieldName, r);
break;
}
}
instance.Status = DownloadStatus.Stopped;
list.Add(instance);
}
return list;
}
public static List<FinishedDownloadEntry> DeserializeFinishedDownloadEntry(BinaryReader r)
{
var count = r.ReadInt32();
var list = new List<FinishedDownloadEntry>(count);
for (int i = 0; i < count; i++)
{
var instance = new FinishedDownloadEntry();
var fieldsCount = r.ReadInt16();
for (var j = 0; j < fieldsCount; j++)
{
var fieldName = r.ReadString();
var fieldType = r.ReadByte();
switch (fieldName)
{
case "Id":
instance.Id = r.ReadString();
break;
case "Name":
instance.Name = r.ReadString();
break;
case "DateAdded":
instance.DateAdded = DateTime.FromBinary(r.ReadInt64());
break;
case "DownloadType":
instance.DownloadType = r.ReadString();
break;
case "FileNameFetchMode":
instance.FileNameFetchMode = (FileNameFetchMode)r.ReadInt32();
break;
case "MaxSpeedLimitInKiB":
instance.MaxSpeedLimitInKiB = r.ReadInt32();
break;
case "Size":
instance.Size = r.ReadInt64();
break;
case "PrimaryUrl":
instance.PrimaryUrl = r.ReadString();
break;
case "TargetDir":
instance.TargetDir = r.ReadString();
break;
case "RefererUrl":
instance.RefererUrl = r.ReadString();
break;
case "Authentication":
var authenticationInfoFieldLength = r.ReadInt16();
var authenticationInfo = new AuthenticationInfo();
for (int b = 0; b < authenticationInfoFieldLength; b++)
{
var fieldName1 = r.ReadString();
var fieldType1 = r.ReadByte();
switch (fieldName1)
{
case "User":
authenticationInfo.UserName = r.ReadString();
break;
case "Password":
authenticationInfo.Password = r.ReadString();
break;
default:
SkipUnknownField(fieldType1, fieldName1, r);
break;
}
}
break;
case "Proxy":
instance.Proxy = DeserializeProxyInfo(r);
break;
default:
SkipUnknownField(fieldType, fieldName, r);
break;
}
}
list.Add(instance);
}
return list;
}
public static void SerializeInProgressDownloadEntry(BinaryWriter w, List<InProgressDownloadEntry> list)
{
w.Write(list.Count);
for (int i = 0; i < list.Count; i++)
{
var fieldCount = 8;
var ent = list[i];
if (!string.IsNullOrEmpty(ent.PrimaryUrl))
{
fieldCount++;
}
if (!string.IsNullOrEmpty(ent.TargetDir))
{
fieldCount++;
}
if (!string.IsNullOrEmpty(ent.RefererUrl))
{
fieldCount++;
}
if (ent.Authentication != null)
{
fieldCount++;
}
if (ent.Proxy != null)
{
fieldCount++;
}
w.Write((short)fieldCount);
WriteString(w, ent.Id, "Id");
WriteString(w, ent.Name, "Name");
WriteInt64(w, ent.DateAdded.ToBinary(), "DateAdded");
WriteString(w, ent.DownloadType, "DownloadType");
WriteInt32(w, (int)ent.FileNameFetchMode, "FileNameFetchMode");
WriteInt32(w, ent.MaxSpeedLimitInKiB, "MaxSpeedLimitInKiB");
WriteInt32(w, ent.Progress, "Progress");
WriteInt64(w, ent.Size, "Size");
if (!string.IsNullOrEmpty(ent.PrimaryUrl))
{
WriteString(w, ent.PrimaryUrl, "PrimaryUrl");
}
if (!string.IsNullOrEmpty(ent.TargetDir))
{
WriteString(w, ent.TargetDir, "TargetDir");
}
if (!string.IsNullOrEmpty(ent.RefererUrl))
{
WriteString(w, ent.RefererUrl, "RefererUrl");
}
if (ent.Authentication != null)
{
w.Write("Authentication");
w.Write(OBJECT);
w.Write((short)2); //no of fields in Authentication class
WriteString(w, ent.Authentication.Value.UserName, "User");
WriteString(w, ent.Authentication.Value.Password, "Password");
}
if (ent.Proxy != null)
{
ProxyInfoSerializer.Serialize(ent.Proxy.Value, w);
}
}
}
public static void SerializeFinishedDownloadEntry(BinaryWriter w, List<FinishedDownloadEntry> list)
{
w.Write(list.Count);
for (int i = 0; i < list.Count; i++)
{
var fieldCount = 7;
var ent = list[i];
if (!string.IsNullOrEmpty(ent.PrimaryUrl))
{
fieldCount++;
}
if (!string.IsNullOrEmpty(ent.TargetDir))
{
fieldCount++;
}
if (!string.IsNullOrEmpty(ent.RefererUrl))
{
fieldCount++;
}
if (ent.Authentication != null)
{
fieldCount++;
}
if (ent.Proxy != null)
{
fieldCount++;
}
w.Write((short)fieldCount);
WriteString(w, ent.Id, "Id");
WriteString(w, ent.Name, "Name");
WriteInt64(w, ent.DateAdded.ToBinary(), "DateAdded");
WriteString(w, ent.DownloadType, "DownloadType");
WriteInt32(w, (int)ent.FileNameFetchMode, "FileNameFetchMode");
WriteInt32(w, ent.MaxSpeedLimitInKiB, "MaxSpeedLimitInKiB");
WriteInt64(w, ent.Size, "Size");
if (!string.IsNullOrEmpty(ent.PrimaryUrl))
{
WriteString(w, ent.PrimaryUrl, "PrimaryUrl");
}
if (!string.IsNullOrEmpty(ent.TargetDir))
{
WriteString(w, ent.TargetDir, "TargetDir");
}
if (!string.IsNullOrEmpty(ent.RefererUrl))
{
WriteString(w, ent.RefererUrl, "RefererUrl");
}
if (ent.Authentication != null)
{
w.Write("Authentication");
w.Write(OBJECT);
w.Write((short)2); //no of fields in Authentication class
WriteString(w, ent.Authentication.Value.UserName, "User");
WriteString(w, ent.Authentication.Value.Password, "Password");
}
if (ent.Proxy != null)
{
ProxyInfoSerializer.Serialize(ent.Proxy.Value, w);
}
}
}
}
}

View File

@ -12,7 +12,7 @@ namespace XDM.Core
{
public static void Serialize(ProxyInfo proxy, BinaryWriter w)
{
SerializationHelper.SerializeProxyInfo(proxy, w);
ConfigIO.SerializeProxyInfo(proxy, w);
}
//public static ProxyInfo? Deserialize(BinaryReader reader)
@ -34,7 +34,7 @@ namespace XDM.Core
public static ProxyInfo Deserialize(BinaryReader r)
{
return SerializationHelper.DeserializeProxyInfo(r);
return ConfigIO.DeserializeProxyInfo(r);
}
}
}

View File

@ -26,7 +26,7 @@ namespace XDM.Core.UI
string? referer = null;
if (item.DownloadType == "Http")
{
var state = DownloadStateStore.LoadSingleSourceHTTPDownloaderState(item.Id);
var state = DownloadStateIO.LoadSingleSourceHTTPDownloaderState(item.Id);
referer = GetReferer(state.Headers);
//if (!TransactedIO.ReadStream(item.Id + ".state", Config.DataDir, s =>
//{
@ -45,7 +45,7 @@ namespace XDM.Core.UI
}
else if (item.DownloadType == "Dash")
{
var state = DownloadStateStore.LoadDualSourceHTTPDownloaderState(item.Id);
var state = DownloadStateIO.LoadDualSourceHTTPDownloaderState(item.Id);
//JsonConvert.DeserializeObject<DualSourceHTTPDownloaderState>(
// File.ReadAllText(Path.Combine(Config.DataDir, item.Id + ".state")));
referer = GetReferer(state.Headers1);

View File

@ -237,7 +237,7 @@ namespace XDM.Core
switch (ent.DownloadType)
{
case "Http":
var s = DownloadStateStore.LoadSingleSourceHTTPDownloaderState(ent.Id);
var s = DownloadStateIO.LoadSingleSourceHTTPDownloaderState(ent.Id);
state = new()
{
Headers = s.Headers,
@ -245,7 +245,7 @@ namespace XDM.Core
};
break;
case "Dash":
var d = DownloadStateStore.LoadDualSourceHTTPDownloaderState(ent.Id);
var d = DownloadStateIO.LoadDualSourceHTTPDownloaderState(ent.Id);
state = new()
{
Headers1 = d.Headers1,
@ -255,7 +255,7 @@ namespace XDM.Core
};
break;
case "Hls":
var h = DownloadStateStore.LoadMultiSourceHLSDownloadState(ent.Id);
var h = DownloadStateIO.LoadMultiSourceHLSDownloadState(ent.Id);
state = new()
{
Headers = h.Headers,
@ -263,7 +263,7 @@ namespace XDM.Core
};
break;
case "Mpd-Dash":
var m = DownloadStateStore.LoadMultiSourceDASHDownloadState(ent.Id);
var m = DownloadStateIO.LoadMultiSourceDASHDownloadState(ent.Id);
state = new()
{
Headers = m.Headers,

View File

@ -136,7 +136,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Downloader\Chunk.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Downloader\CountdownLatch.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Downloader\DownloadFailedEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)IO\DownloadStateStore.cs" />
<Compile Include="..\XDM.Core\IO\DownloadStateIO.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Downloader\DownloadTypes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Downloader\FileNameFetchMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Downloader\IBaseDownloader.cs" />
@ -172,7 +172,7 @@
<Compile Include="$(MSBuildThisFileDirectory)UI\QueueSelectionEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Util\BrowserLauncher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Util\Helpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)IO\SerializationHelper.cs" />
<Compile Include="..\XDM.Core\IO\ConfigIO.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Util\TimeHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Util\Win32NativeMethods.cs" />
<Compile Include="..\XDM.Core\Application.cs" />