Browse compressed file content
This commit is contained in:
@@ -6,12 +6,12 @@ namespace FileTime.Core.ContentAccess;
|
|||||||
|
|
||||||
public interface ISubContentProvider
|
public interface ISubContentProvider
|
||||||
{
|
{
|
||||||
|
Task<bool> CanHandleAsync(IElement parentElement);
|
||||||
|
|
||||||
Task<IItem?> GetItemByFullNameAsync(
|
Task<IItem?> GetItemByFullNameAsync(
|
||||||
IElement parentElement,
|
IElement parentElement,
|
||||||
FullName itemPath,
|
FullName itemPath,
|
||||||
PointInTime pointInTime,
|
PointInTime pointInTime,
|
||||||
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
||||||
ItemInitializationSettings itemInitializationSettings = default);
|
ItemInitializationSettings itemInitializationSettings = default);
|
||||||
|
|
||||||
Task<bool> CanHandleAsync(IElement parentElement);
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using FileTime.Core.ContentAccess;
|
||||||
|
|
||||||
|
namespace FileTime.Tools.Compression.ContentProvider;
|
||||||
|
|
||||||
|
public interface ICompressedContentProvider : IContentProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using FileTime.Core.ContentAccess;
|
||||||
|
|
||||||
|
namespace FileTime.Tools.Compression.ContentProvider;
|
||||||
|
|
||||||
|
public interface ICompressedContentProviderFactory
|
||||||
|
{
|
||||||
|
ICompressedContentProvider Create(IContentProvider parentContentProvider);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using FileTime.Core.ContentAccess;
|
||||||
|
|
||||||
|
namespace FileTime.Tools.Compression.ContentProvider;
|
||||||
|
|
||||||
|
public interface ICompressedSubContentProvider : ISubContentProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,4 +15,5 @@
|
|||||||
<ProjectReference Include="..\..\Core\FileTime.Core.Abstraction\FileTime.Core.Abstraction.csproj" />
|
<ProjectReference Include="..\..\Core\FileTime.Core.Abstraction\FileTime.Core.Abstraction.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using SharpCompress.Archives;
|
|||||||
using SharpCompress.Common;
|
using SharpCompress.Common;
|
||||||
using SharpCompressCompressionType = SharpCompress.Common.CompressionType;
|
using SharpCompressCompressionType = SharpCompress.Common.CompressionType;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression.Compress;
|
||||||
|
|
||||||
public class CompressCommand : CommandBase, IExecutableCommand, ITransportationCommand, IRequireInputCommand
|
public class CompressCommand : CommandBase, IExecutableCommand, ITransportationCommand, IRequireInputCommand
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,7 @@ using FileTime.Core.Interactions;
|
|||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.Core.Timeline;
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression.Compress;
|
||||||
|
|
||||||
public class CompressCommandFactory : ITransportationCommandFactory<CompressCommand>
|
public class CompressCommandFactory : ITransportationCommandFactory<CompressCommand>
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using FileTime.App.Core.UserCommand;
|
using FileTime.App.Core.UserCommand;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression.Compress;
|
||||||
|
|
||||||
public class CompressUserCommand : IIdentifiableUserCommand
|
public class CompressUserCommand : IIdentifiableUserCommand
|
||||||
{
|
{
|
||||||
@@ -4,6 +4,8 @@ using FileTime.App.Core.Services;
|
|||||||
using FileTime.App.Core.Services.UserCommandHandler;
|
using FileTime.App.Core.Services.UserCommandHandler;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
|
using FileTime.Tools.Compression.Compress;
|
||||||
|
using FileTime.Tools.Compression.Decompress;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Text;
|
||||||
|
using FileTime.Core.ContentAccess;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.Tools.Compression.ContentProvider;
|
||||||
|
|
||||||
|
public class CompressedContentProvider : SubContentProviderBase, ICompressedContentProvider
|
||||||
|
{
|
||||||
|
public CompressedContentProvider(
|
||||||
|
IContentProvider parentContentProvider,
|
||||||
|
ITimelessContentProvider timelessContentProvider
|
||||||
|
)
|
||||||
|
: base(parentContentProvider, "compression", timelessContentProvider)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default)
|
||||||
|
=> Task.FromResult((byte[]?)"Not implemented..."u8.ToArray());
|
||||||
|
|
||||||
|
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => throw new NotImplementedException();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using FileTime.Core.ContentAccess;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.Tools.Compression.ContentProvider;
|
||||||
|
|
||||||
|
public class CompressedContentProviderFactory : ICompressedContentProviderFactory
|
||||||
|
{
|
||||||
|
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||||
|
|
||||||
|
public CompressedContentProviderFactory(ITimelessContentProvider timelessContentProvider)
|
||||||
|
{
|
||||||
|
_timelessContentProvider = timelessContentProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICompressedContentProvider Create(IContentProvider parentContentProvider)
|
||||||
|
{
|
||||||
|
return new CompressedContentProvider(parentContentProvider, _timelessContentProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using FileTime.Core.ContentAccess;
|
||||||
|
using FileTime.Core.Enums;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
using SharpCompress.Archives;
|
||||||
|
using IContainer = FileTime.Core.Models.IContainer;
|
||||||
|
|
||||||
|
namespace FileTime.Tools.Compression.ContentProvider;
|
||||||
|
|
||||||
|
public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||||
|
{
|
||||||
|
private static readonly string[] SupportedExtensions = {".zip", ".gz", ".7z"};
|
||||||
|
|
||||||
|
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||||
|
private readonly ICompressedContentProviderFactory _compressedContentProviderFactory;
|
||||||
|
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||||
|
|
||||||
|
public CompressedSubContentProvider(
|
||||||
|
IContentAccessorFactory contentAccessorFactory,
|
||||||
|
ICompressedContentProviderFactory compressedContentProviderFactory,
|
||||||
|
ITimelessContentProvider timelessContentProvider
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_contentAccessorFactory = contentAccessorFactory;
|
||||||
|
_compressedContentProviderFactory = compressedContentProviderFactory;
|
||||||
|
_timelessContentProvider = timelessContentProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> CanHandleAsync(IElement parentElement)
|
||||||
|
=> Task.FromResult(
|
||||||
|
parentElement.NativePath?.Path is { } path
|
||||||
|
&& SupportedExtensions.Any(e => path.EndsWith(e))
|
||||||
|
);
|
||||||
|
|
||||||
|
public async Task<IItem?> GetItemByFullNameAsync(
|
||||||
|
IElement parentElement,
|
||||||
|
FullName itemPath,
|
||||||
|
PointInTime pointInTime,
|
||||||
|
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
||||||
|
ItemInitializationSettings itemInitializationSettings = default)
|
||||||
|
{
|
||||||
|
var parentContentReader = await _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider).CreateContentReaderAsync(parentElement);
|
||||||
|
var parentContentReaderStream = parentContentReader.AsStream();
|
||||||
|
var archive = ArchiveFactory.Open(parentContentReaderStream);
|
||||||
|
var disposables = new IDisposable[] {parentContentReader, parentContentReaderStream, archive};
|
||||||
|
|
||||||
|
if (itemPath.Path.Length == 0 || itemPath.Path == Constants.SubContentProviderRootContainer)
|
||||||
|
{
|
||||||
|
var rootFullNameBase = parentElement.FullName!.Path + Constants.SeparatorChar + Constants.SubContentProviderRootContainer;
|
||||||
|
var rootNativePathBase = parentElement.NativePath!.Path + Constants.SeparatorChar + Constants.SubContentProviderRootContainer;
|
||||||
|
|
||||||
|
var rootFullName = new FullName(rootFullNameBase);
|
||||||
|
var rootNativePath = new NativePath(rootNativePathBase);
|
||||||
|
|
||||||
|
var container = CreateContainer(
|
||||||
|
archive,
|
||||||
|
new FullName(":/"),
|
||||||
|
rootFullName,
|
||||||
|
rootNativePath,
|
||||||
|
parentElement,
|
||||||
|
parentElement.Parent!,
|
||||||
|
itemInitializationSettings,
|
||||||
|
disposables
|
||||||
|
);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResolveNonRootChild(
|
||||||
|
archive,
|
||||||
|
parentElement,
|
||||||
|
itemPath,
|
||||||
|
itemInitializationSettings,
|
||||||
|
disposables
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IItem ResolveNonRootChild(
|
||||||
|
IArchive archive,
|
||||||
|
IElement parentElement,
|
||||||
|
FullName itemPath,
|
||||||
|
ItemInitializationSettings itemInitializationSettings,
|
||||||
|
ICollection<IDisposable> disposables)
|
||||||
|
{
|
||||||
|
var childFullNameBase = parentElement.FullName!.Path + Constants.SeparatorChar + itemPath.Path;
|
||||||
|
var childNativePathBase = parentElement.NativePath!.Path + Constants.SeparatorChar + itemPath.Path;
|
||||||
|
|
||||||
|
var childFullName = new FullName(childFullNameBase);
|
||||||
|
var childNativePath = new NativePath(childNativePathBase);
|
||||||
|
|
||||||
|
var isDirectory = false;
|
||||||
|
var path = itemPath.Path
|
||||||
|
.Substring(1 + Constants.SubContentProviderRootContainer.Length)
|
||||||
|
.Replace(Constants.SeparatorChar, '/');
|
||||||
|
|
||||||
|
var pathWithSlash = path + '/';
|
||||||
|
var size = 0L;
|
||||||
|
foreach (var archiveEntry in archive.Entries)
|
||||||
|
{
|
||||||
|
if (archiveEntry.Key == path)
|
||||||
|
{
|
||||||
|
if (archiveEntry.IsDirectory)
|
||||||
|
{
|
||||||
|
isDirectory = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = archiveEntry.Size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (archiveEntry.Key.StartsWith(pathWithSlash))
|
||||||
|
{
|
||||||
|
isDirectory = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent = new AbsolutePath(
|
||||||
|
_timelessContentProvider,
|
||||||
|
parentElement.PointInTime,
|
||||||
|
childFullName.GetParent()!,
|
||||||
|
AbsolutePathType.Container
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDirectory)
|
||||||
|
{
|
||||||
|
return CreateContainer(
|
||||||
|
archive,
|
||||||
|
itemPath,
|
||||||
|
childFullName,
|
||||||
|
childNativePath,
|
||||||
|
parentElement,
|
||||||
|
parent,
|
||||||
|
itemInitializationSettings,
|
||||||
|
disposables
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var element = CreateElement(
|
||||||
|
itemPath,
|
||||||
|
childFullName,
|
||||||
|
childNativePath,
|
||||||
|
parentElement,
|
||||||
|
parent,
|
||||||
|
size);
|
||||||
|
|
||||||
|
foreach (var disposable in disposables)
|
||||||
|
{
|
||||||
|
disposable.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IContainer CreateContainer(
|
||||||
|
IArchive archive,
|
||||||
|
FullName itemPath,
|
||||||
|
FullName fullName,
|
||||||
|
NativePath nativePath,
|
||||||
|
IElement parentElement,
|
||||||
|
AbsolutePath parent,
|
||||||
|
ItemInitializationSettings initializationSettings,
|
||||||
|
ICollection<IDisposable> disposables)
|
||||||
|
{
|
||||||
|
var name = itemPath.Path.Split(Constants.SeparatorChar).Last();
|
||||||
|
|
||||||
|
var children = new ObservableCollection<AbsolutePath>();
|
||||||
|
var exceptions = new ObservableCollection<Exception>();
|
||||||
|
|
||||||
|
var container = new Container(
|
||||||
|
name,
|
||||||
|
name,
|
||||||
|
fullName,
|
||||||
|
nativePath,
|
||||||
|
parent,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
parentElement.CreatedAt,
|
||||||
|
parentElement.ModifiedAt,
|
||||||
|
SupportsDelete.False,
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
_compressedContentProviderFactory.Create(parentElement.Provider),
|
||||||
|
false,
|
||||||
|
parentElement.PointInTime,
|
||||||
|
exceptions,
|
||||||
|
new ReadOnlyExtensionCollection(new ExtensionCollection()),
|
||||||
|
children
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!initializationSettings.SkipChildInitialization)
|
||||||
|
{
|
||||||
|
LoadChildren(archive, container, itemPath, parentElement.PointInTime, children, exceptions);
|
||||||
|
ThreadPool.QueueUserWorkItem(_ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
container.StartLoading();
|
||||||
|
//LoadChildren(archive, container, itemPath, parentElement.PointInTime, children, exceptions);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
container.StopLoading();
|
||||||
|
foreach (var disposable in disposables)
|
||||||
|
{
|
||||||
|
disposable.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadChildren(
|
||||||
|
IArchive archive,
|
||||||
|
Container container,
|
||||||
|
FullName itemPath,
|
||||||
|
PointInTime pointInTime,
|
||||||
|
ObservableCollection<AbsolutePath> children,
|
||||||
|
ObservableCollection<Exception> exceptions)
|
||||||
|
{
|
||||||
|
var containerPath = itemPath.Path
|
||||||
|
.Substring(1 + Constants.SubContentProviderRootContainer.Length);
|
||||||
|
var containerLevel = containerPath.Length != 0
|
||||||
|
? containerPath.Split(Constants.SeparatorChar).Length
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
var addedContainers = new List<string>();
|
||||||
|
foreach (var archiveEntry in archive.Entries)
|
||||||
|
{
|
||||||
|
if (!archiveEntry.Key.StartsWith(containerPath)) continue;
|
||||||
|
|
||||||
|
var childPathParts = archiveEntry.Key.TrimEnd('/').Split('/');
|
||||||
|
if (childPathParts.Length < containerLevel + 1) continue;
|
||||||
|
var itemName = childPathParts[containerLevel];
|
||||||
|
|
||||||
|
if ((archiveEntry.IsDirectory && childPathParts.Length == containerLevel + 1)
|
||||||
|
|| (!archiveEntry.IsDirectory && childPathParts.Length > containerLevel + 1))
|
||||||
|
{
|
||||||
|
//Container
|
||||||
|
if (addedContainers.Contains(itemName)) continue;
|
||||||
|
addedContainers.Add(itemName);
|
||||||
|
|
||||||
|
children.Add(new AbsolutePath(
|
||||||
|
_timelessContentProvider,
|
||||||
|
pointInTime,
|
||||||
|
container.FullName.GetChild(itemName),
|
||||||
|
AbsolutePathType.Container)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (!archiveEntry.IsDirectory && childPathParts.Length == containerLevel + 1)
|
||||||
|
{
|
||||||
|
//Element
|
||||||
|
children.Add(new AbsolutePath(
|
||||||
|
_timelessContentProvider,
|
||||||
|
pointInTime,
|
||||||
|
container.FullName.GetChild(itemName),
|
||||||
|
AbsolutePathType.Element)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IItem CreateElement(FullName itemPath,
|
||||||
|
FullName fullName,
|
||||||
|
NativePath nativePath,
|
||||||
|
IElement parentElement,
|
||||||
|
AbsolutePath parent,
|
||||||
|
long size)
|
||||||
|
{
|
||||||
|
var name = itemPath.Path.Split(Constants.SeparatorChar).Last();
|
||||||
|
|
||||||
|
var exceptions = new ObservableCollection<Exception>();
|
||||||
|
|
||||||
|
var element = new Element(
|
||||||
|
name,
|
||||||
|
name,
|
||||||
|
fullName,
|
||||||
|
nativePath,
|
||||||
|
parent,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
parentElement.CreatedAt,
|
||||||
|
parentElement.ModifiedAt,
|
||||||
|
SupportsDelete.False,
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
size,
|
||||||
|
_compressedContentProviderFactory.Create(parentElement.Provider),
|
||||||
|
parentElement.PointInTime,
|
||||||
|
exceptions,
|
||||||
|
new ReadOnlyExtensionCollection(new ExtensionCollection())
|
||||||
|
);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using FileTime.Core.Models;
|
|||||||
using FileTime.Core.Timeline;
|
using FileTime.Core.Timeline;
|
||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression.Decompress;
|
||||||
|
|
||||||
public class DecompressCommand : CommandBase, IExecutableCommand, ITransportationCommand, IDisposable
|
public class DecompressCommand : CommandBase, IExecutableCommand, ITransportationCommand, IDisposable
|
||||||
{
|
{
|
||||||
@@ -3,7 +3,7 @@ using FileTime.Core.ContentAccess;
|
|||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.Core.Timeline;
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression.Decompress;
|
||||||
|
|
||||||
public class DecompressCommandFactory : ITransportationCommandFactory<DecompressCommand>
|
public class DecompressCommandFactory : ITransportationCommandFactory<DecompressCommand>
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using FileTime.App.Core.UserCommand;
|
using FileTime.App.Core.UserCommand;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression.Decompress;
|
||||||
|
|
||||||
public class DecompressUserCommand : IIdentifiableUserCommand
|
public class DecompressUserCommand : IIdentifiableUserCommand
|
||||||
{
|
{
|
||||||
@@ -9,8 +9,12 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\AppCommon\FileTime.App.Core.Abstraction\FileTime.App.Core.Abstraction.csproj" />
|
<ProjectReference Include="..\..\AppCommon\FileTime.App.Core.Abstraction\FileTime.App.Core.Abstraction.csproj" />
|
||||||
<ProjectReference Include="..\..\Core\FileTime.Core.Command\FileTime.Core.Command.csproj" />
|
<ProjectReference Include="..\..\Core\FileTime.Core.Command\FileTime.Core.Command.csproj" />
|
||||||
|
<ProjectReference Include="..\..\Core\FileTime.Core.ContentAccess\FileTime.Core.ContentAccess.csproj" />
|
||||||
|
<ProjectReference Include="..\..\Core\FileTime.Core.Models\FileTime.Core.Models.csproj" />
|
||||||
<ProjectReference Include="..\FileTime.Tools.Compression.Core\FileTime.Tools.Compression.Core.csproj" />
|
<ProjectReference Include="..\FileTime.Tools.Compression.Core\FileTime.Tools.Compression.Core.csproj" />
|
||||||
<ProjectReference Include="..\FileTime.Tools\FileTime.Tools.csproj" />
|
<ProjectReference Include="..\FileTime.Tools\FileTime.Tools.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
|
using FileTime.Core.ContentAccess;
|
||||||
|
using FileTime.Tools.Compression.Compress;
|
||||||
|
using FileTime.Tools.Compression.ContentProvider;
|
||||||
|
using FileTime.Tools.Compression.Decompress;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
namespace FileTime.Tools.Compression;
|
namespace FileTime.Tools.Compression;
|
||||||
|
|
||||||
@@ -21,6 +26,8 @@ public static class Startup
|
|||||||
services.AddSingleton<CompressCommandFactory>();
|
services.AddSingleton<CompressCommandFactory>();
|
||||||
services.AddSingleton<DecompressCommandFactory>();
|
services.AddSingleton<DecompressCommandFactory>();
|
||||||
services.AddSingleton<IUserCommandHandler, CompressionUserCommandHandler>();
|
services.AddSingleton<IUserCommandHandler, CompressionUserCommandHandler>();
|
||||||
|
services.TryAddSingleton<ICompressedContentProviderFactory, CompressedContentProviderFactory>();
|
||||||
|
services.AddSingleton<ISubContentProvider, CompressedSubContentProvider>();
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,6 @@ public class VirtualDiskContentProvider : SubContentProviderBase, IVirtualDiskCo
|
|||||||
var parentItem = await ParentContentProvider.GetItemByNativePathAsync(supportedPath, element.PointInTime);
|
var parentItem = await ParentContentProvider.GetItemByNativePathAsync(supportedPath, element.PointInTime);
|
||||||
if (parentItem is not IElement parentElement) return null;
|
if (parentItem is not IElement parentElement) return null;
|
||||||
|
|
||||||
|
|
||||||
var contentReaderFactory = _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
|
var contentReaderFactory = _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
|
||||||
var reader = await contentReaderFactory.CreateContentReaderAsync(parentElement);
|
var reader = await contentReaderFactory.CreateContentReaderAsync(parentElement);
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,12 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
|
|||||||
var childFullName = new FullName(childFullNameBase);
|
var childFullName = new FullName(childFullNameBase);
|
||||||
var childNativePath = new NativePath(childNativePathBase);
|
var childNativePath = new NativePath(childNativePathBase);
|
||||||
|
|
||||||
var parent = new AbsolutePath(_timelessContentProvider, pointInTime, childFullName.GetParent()!, AbsolutePathType.Container);
|
var parent = new AbsolutePath(
|
||||||
|
_timelessContentProvider,
|
||||||
|
pointInTime,
|
||||||
|
childFullName.GetParent()!,
|
||||||
|
AbsolutePathType.Container
|
||||||
|
);
|
||||||
|
|
||||||
var container = discReader.Root;
|
var container = discReader.Root;
|
||||||
for (var i = 1; i < pathParts.Length - 1; i++)
|
for (var i = 1; i < pathParts.Length - 1; i++)
|
||||||
@@ -125,7 +130,7 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
|
|||||||
private IContainer CreateContainer(
|
private IContainer CreateContainer(
|
||||||
UdfReader discReader,
|
UdfReader discReader,
|
||||||
DiscDirectoryInfo sourceContainer,
|
DiscDirectoryInfo sourceContainer,
|
||||||
FullName fullname,
|
FullName fullName,
|
||||||
NativePath nativePath,
|
NativePath nativePath,
|
||||||
IContentProvider parentContentProvider,
|
IContentProvider parentContentProvider,
|
||||||
AbsolutePath parent,
|
AbsolutePath parent,
|
||||||
@@ -137,7 +142,7 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
|
|||||||
var container = new Container(
|
var container = new Container(
|
||||||
sourceContainer.Name,
|
sourceContainer.Name,
|
||||||
sourceContainer.Name,
|
sourceContainer.Name,
|
||||||
fullname,
|
fullName,
|
||||||
nativePath,
|
nativePath,
|
||||||
parent,
|
parent,
|
||||||
true,
|
true,
|
||||||
@@ -159,8 +164,16 @@ public class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
|
|||||||
{
|
{
|
||||||
ThreadPool.QueueUserWorkItem(_ =>
|
ThreadPool.QueueUserWorkItem(_ =>
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
container.StartLoading();
|
||||||
LoadChildren(container, sourceContainer, children, pointInTime, exceptions);
|
LoadChildren(container, sourceContainer, children, pointInTime, exceptions);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
discReader.Dispose();
|
discReader.Dispose();
|
||||||
|
container.StopLoading();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user