Use primary constructors
This commit is contained in:
@@ -3,9 +3,9 @@ using PropertyChanged.SourceGenerator;
|
||||
|
||||
namespace FileTime.Core.Interactions;
|
||||
|
||||
public partial class OptionsInputElement<T> : InputElementBase, IOptionsInputElement, INotifyPropertyChanged
|
||||
public partial class OptionsInputElement<T>(string label, IEnumerable<OptionElement<T>> options) : InputElementBase(label, InputType.Options), IOptionsInputElement, INotifyPropertyChanged
|
||||
{
|
||||
public IReadOnlyCollection<OptionElement<T>> Options { get; }
|
||||
public IReadOnlyCollection<OptionElement<T>> Options { get; } = Enumerable.ToList<OptionElement<T>>(options);
|
||||
|
||||
[Notify] private T? _value;
|
||||
|
||||
@@ -26,9 +26,4 @@ public partial class OptionsInputElement<T> : InputElementBase, IOptionsInputEle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OptionsInputElement(string label, IEnumerable<OptionElement<T>> options) : base(label, InputType.Options)
|
||||
{
|
||||
Options = options.ToList();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
namespace GeneralInputKey;
|
||||
|
||||
public class GeneralKeyEventArgs
|
||||
public class GeneralKeyEventArgs(Action<bool>? handledChanged = null)
|
||||
{
|
||||
private readonly Action<bool>? _handledChanged;
|
||||
private bool _handled;
|
||||
public required Keys? Key { get; init; }
|
||||
public required char KeyChar { get; init; }
|
||||
@@ -16,13 +15,8 @@ public class GeneralKeyEventArgs
|
||||
if (_handled != value)
|
||||
{
|
||||
_handled = value;
|
||||
_handledChanged?.Invoke(value);
|
||||
handledChanged?.Invoke(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GeneralKeyEventArgs(Action<bool>? handledChanged = null)
|
||||
{
|
||||
_handledChanged = handledChanged;
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,8 @@ using TerminalUI.TextFormat;
|
||||
|
||||
namespace TerminalUI.Examples.Controls;
|
||||
|
||||
public class ProgressBarExamples
|
||||
public class ProgressBarExamples(IApplicationContext applicationContext)
|
||||
{
|
||||
private readonly IApplicationContext _applicationContext;
|
||||
private static readonly IConsoleDriver _driver;
|
||||
|
||||
static ProgressBarExamples()
|
||||
@@ -16,11 +15,6 @@ public class ProgressBarExamples
|
||||
_driver.Init();
|
||||
}
|
||||
|
||||
public ProgressBarExamples(IApplicationContext applicationContext)
|
||||
{
|
||||
_applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public void LoadingExample()
|
||||
{
|
||||
var progressBar = CreateProgressBar<object>(0);
|
||||
@@ -46,7 +40,7 @@ public class ProgressBarExamples
|
||||
{
|
||||
Value = percent,
|
||||
Attached = true,
|
||||
ApplicationContext = _applicationContext
|
||||
ApplicationContext = applicationContext
|
||||
};
|
||||
|
||||
private void RenderProgressBar<T>(ProgressBar<T> progressBar, Position position)
|
||||
|
||||
@@ -6,13 +6,7 @@ namespace TerminalUI.Tests.Models;
|
||||
|
||||
public sealed partial class TestViewModel : INotifyPropertyChanged
|
||||
{
|
||||
[Notify] private List<TestNestedCollectionItem> _items;
|
||||
[Notify] private string _text;
|
||||
|
||||
public TestViewModel()
|
||||
{
|
||||
_text = "Initial text";
|
||||
_items = new List<TestNestedCollectionItem>
|
||||
[Notify] private List<TestNestedCollectionItem> _items = new()
|
||||
{
|
||||
TestNestedCollectionItem.Create(
|
||||
3,
|
||||
@@ -23,7 +17,7 @@ public sealed partial class TestViewModel : INotifyPropertyChanged
|
||||
new()
|
||||
)
|
||||
};
|
||||
}
|
||||
[Notify] private string _text = "Initial text";
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ using TerminalUI.Styling;
|
||||
|
||||
namespace TerminalUI;
|
||||
|
||||
public class ApplicationContext : IApplicationContext
|
||||
public class ApplicationContext(IServiceProvider serviceProvider) : IApplicationContext
|
||||
{
|
||||
private readonly Lazy<IConsoleDriver> _consoleDriver;
|
||||
private readonly Lazy<IFocusManager> _focusManager;
|
||||
private readonly Lazy<ILoggerFactory?> _loggerFactory;
|
||||
private readonly Lazy<IRenderEngine> _renderEngine;
|
||||
private readonly Lazy<IConsoleDriver> _consoleDriver = new Lazy<IConsoleDriver>(serviceProvider.GetRequiredService<IConsoleDriver>);
|
||||
private readonly Lazy<IFocusManager> _focusManager = new Lazy<IFocusManager>(serviceProvider.GetRequiredService<IFocusManager>);
|
||||
private readonly Lazy<ILoggerFactory?> _loggerFactory = new Lazy<ILoggerFactory?>(serviceProvider.GetService<ILoggerFactory?>);
|
||||
private readonly Lazy<IRenderEngine> _renderEngine = new Lazy<IRenderEngine>(serviceProvider.GetRequiredService<IRenderEngine>);
|
||||
|
||||
public IConsoleDriver ConsoleDriver => _consoleDriver.Value;
|
||||
public IFocusManager FocusManager => _focusManager.Value;
|
||||
@@ -20,12 +20,4 @@ public class ApplicationContext : IApplicationContext
|
||||
public bool IsRunning { get; set; }
|
||||
public char EmptyCharacter { get; init; } = ' ';
|
||||
public bool SupportUtf8Output { get; set; } = true;
|
||||
|
||||
public ApplicationContext(IServiceProvider serviceProvider)
|
||||
{
|
||||
_consoleDriver = new Lazy<IConsoleDriver>(serviceProvider.GetRequiredService<IConsoleDriver>);
|
||||
_focusManager = new Lazy<IFocusManager>(serviceProvider.GetRequiredService<IFocusManager>);
|
||||
_loggerFactory = new Lazy<ILoggerFactory?>(serviceProvider.GetService<ILoggerFactory?>);
|
||||
_renderEngine = new Lazy<IRenderEngine>(serviceProvider.GetRequiredService<IRenderEngine>);
|
||||
}
|
||||
}
|
||||
@@ -7,31 +7,24 @@ namespace TerminalUI.Controls;
|
||||
public record ChildWithDataContextMapper<TSourceDataContext, TTargetDataContext>(IView<TTargetDataContext> Child, Func<TSourceDataContext?, TTargetDataContext?> DataContextMapper);
|
||||
public record ChildWithDataContextBinding<TSourceDataContext, TTargetDataContext>(IView<TTargetDataContext> Child, Expression<Func<TSourceDataContext?, TTargetDataContext?>> DataContextExpression);
|
||||
|
||||
public class ChildInitializer<T> : IEnumerable<IView>
|
||||
public class ChildInitializer<T>(IChildContainer<T> childContainer) : IEnumerable<IView>
|
||||
{
|
||||
private readonly IChildContainer<T> _childContainer;
|
||||
|
||||
public ChildInitializer(IChildContainer<T> childContainer)
|
||||
{
|
||||
_childContainer = childContainer;
|
||||
}
|
||||
|
||||
public void Add(IView<T> item) => _childContainer.AddChild(item);
|
||||
public void Add(IView<T> item) => childContainer.AddChild(item);
|
||||
|
||||
public void Add<TDataContext>(ChildWithDataContextMapper<T, TDataContext> item)
|
||||
=> _childContainer.AddChild(item.Child, item.DataContextMapper);
|
||||
=> childContainer.AddChild(item.Child, item.DataContextMapper);
|
||||
|
||||
public void Add<TDataContext>(ChildWithDataContextBinding<T, TDataContext> item)
|
||||
{
|
||||
item.Child.Bind(
|
||||
_childContainer,
|
||||
childContainer,
|
||||
item.DataContextExpression,
|
||||
c => c.DataContext
|
||||
);
|
||||
_childContainer.AddChild(item.Child);
|
||||
childContainer.AddChild(item.Child);
|
||||
}
|
||||
|
||||
public IEnumerator<IView> GetEnumerator() => _childContainer.Children.GetEnumerator();
|
||||
public IEnumerator<IView> GetEnumerator() => childContainer.Children.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
@@ -2,37 +2,30 @@
|
||||
|
||||
namespace TerminalUI;
|
||||
|
||||
public class EventLoop : IEventLoop
|
||||
public class EventLoop(IApplicationContext applicationContext,
|
||||
ILogger<EventLoop> logger)
|
||||
: IEventLoop
|
||||
{
|
||||
private readonly IApplicationContext _applicationContext;
|
||||
private readonly ILogger<EventLoop> _logger;
|
||||
private readonly ILogger<EventLoop> _logger = logger;
|
||||
private readonly List<Action> _initializers = new();
|
||||
private readonly List<Action> _permanentQueue = new();
|
||||
private readonly List<Action> _finalizers = new();
|
||||
|
||||
public int ThreadId { get; set; } = -1;
|
||||
|
||||
public EventLoop(
|
||||
IApplicationContext applicationContext,
|
||||
ILogger<EventLoop> logger)
|
||||
{
|
||||
_applicationContext = applicationContext;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void AddToPermanentQueue(Action action) => _permanentQueue.Add(action);
|
||||
public void AddInitializer(Action action) => _initializers.Add(action);
|
||||
public void AddFinalizer(Action action) => _finalizers.Add(action);
|
||||
|
||||
public void Run()
|
||||
{
|
||||
_applicationContext.IsRunning = true;
|
||||
applicationContext.IsRunning = true;
|
||||
ThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
foreach (var initializer in _initializers)
|
||||
{
|
||||
initializer();
|
||||
}
|
||||
while (_applicationContext.IsRunning)
|
||||
while (applicationContext.IsRunning)
|
||||
{
|
||||
ProcessQueues();
|
||||
Thread.Sleep(10);
|
||||
|
||||
@@ -5,9 +5,8 @@ using TerminalUI.Traits;
|
||||
|
||||
namespace TerminalUI;
|
||||
|
||||
public class FocusManager : IFocusManager
|
||||
public class FocusManager(IRenderEngine renderEngine) : IFocusManager
|
||||
{
|
||||
private readonly IRenderEngine _renderEngine;
|
||||
private IFocusable? _focused;
|
||||
private DateTime _focusLostCandidateTime = DateTime.MinValue;
|
||||
|
||||
@@ -52,11 +51,6 @@ public class FocusManager : IFocusManager
|
||||
private set => _focused = value;
|
||||
}
|
||||
|
||||
public FocusManager(IRenderEngine renderEngine)
|
||||
{
|
||||
_renderEngine = renderEngine;
|
||||
}
|
||||
|
||||
public void SetFocus(IFocusable focusable) => Focused = focusable;
|
||||
|
||||
public void UnFocus(IFocusable focusable)
|
||||
@@ -127,8 +121,8 @@ public class FocusManager : IFocusManager
|
||||
|
||||
if (element is null) return;
|
||||
|
||||
_renderEngine.RequestRerender(element);
|
||||
_renderEngine.RequestRerender(view);
|
||||
renderEngine.RequestRerender(element);
|
||||
renderEngine.RequestRerender(view);
|
||||
Focused = element;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
namespace TerminalUI.Models;
|
||||
|
||||
public readonly ref struct Option<T>
|
||||
public readonly ref struct Option<T>(T value, bool isSome)
|
||||
{
|
||||
public readonly T Value;
|
||||
public readonly bool IsSome;
|
||||
|
||||
public Option(T value, bool isSome)
|
||||
{
|
||||
Value = value;
|
||||
IsSome = isSome;
|
||||
}
|
||||
public readonly T Value = value;
|
||||
public readonly bool IsSome = isSome;
|
||||
}
|
||||
@@ -1,20 +1,12 @@
|
||||
namespace TerminalUI.Models;
|
||||
|
||||
public readonly struct SelectiveChar
|
||||
public readonly struct SelectiveChar(char utf8Char, char asciiChar)
|
||||
{
|
||||
public readonly char Utf8Char;
|
||||
public readonly char AsciiChar;
|
||||
public readonly char Utf8Char = utf8Char;
|
||||
public readonly char AsciiChar = asciiChar;
|
||||
|
||||
public SelectiveChar(char c)
|
||||
public SelectiveChar(char c) : this(c, c)
|
||||
{
|
||||
Utf8Char = c;
|
||||
AsciiChar = c;
|
||||
}
|
||||
|
||||
public SelectiveChar(char utf8Char, char asciiChar)
|
||||
{
|
||||
Utf8Char = utf8Char;
|
||||
AsciiChar = asciiChar;
|
||||
}
|
||||
|
||||
public char GetChar(bool enableUtf8) => enableUtf8 ? Utf8Char : AsciiChar;
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
namespace TerminalUI.TextFormat;
|
||||
|
||||
public readonly struct TextFormatContext
|
||||
public readonly struct TextFormatContext(bool supportsAnsi)
|
||||
{
|
||||
public readonly bool SupportsAnsi;
|
||||
|
||||
public TextFormatContext(bool supportsAnsi)
|
||||
{
|
||||
SupportsAnsi = supportsAnsi;
|
||||
}
|
||||
public readonly bool SupportsAnsi = supportsAnsi;
|
||||
}
|
||||
@@ -6,29 +6,15 @@ using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FileTime.Server.Web;
|
||||
|
||||
public class PortWriterService : IHostedService
|
||||
{
|
||||
private readonly IServer _server;
|
||||
private readonly IHostApplicationLifetime _hostApplicationLifetime;
|
||||
private readonly IOptions<PortWriterConfiguration> _configuration;
|
||||
private readonly ILogger<PortWriterService> _logger;
|
||||
|
||||
public PortWriterService(
|
||||
IServer server,
|
||||
public class PortWriterService(IServer server,
|
||||
IHostApplicationLifetime hostApplicationLifetime,
|
||||
IOptions<PortWriterConfiguration> configuration,
|
||||
ILogger<PortWriterService> logger)
|
||||
: IHostedService
|
||||
{
|
||||
_server = server;
|
||||
_hostApplicationLifetime = hostApplicationLifetime;
|
||||
_configuration = configuration;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_hostApplicationLifetime.ApplicationStarted.Register(WritePort);
|
||||
hostApplicationLifetime.ApplicationStarted.Register(WritePort);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@@ -37,28 +23,28 @@ public class PortWriterService : IHostedService
|
||||
{
|
||||
try
|
||||
{
|
||||
var filename = _configuration.Value.Filename;
|
||||
var filename = configuration.Value.Filename;
|
||||
if (filename is null)
|
||||
{
|
||||
_logger.LogWarning("Could not save port to file as there were no file name given");
|
||||
logger.LogWarning("Could not save port to file as there were no file name given");
|
||||
return;
|
||||
}
|
||||
|
||||
var address = GetAddress();
|
||||
if (address is null)
|
||||
{
|
||||
_logger.LogError("Could not get address");
|
||||
logger.LogError("Could not get address");
|
||||
return;
|
||||
}
|
||||
|
||||
var couldParsePort = int.TryParse(address.Split(':').LastOrDefault(), out var port);
|
||||
if (!couldParsePort)
|
||||
{
|
||||
_logger.LogError("Could not parse port from address {Address}", address);
|
||||
logger.LogError("Could not parse port from address {Address}", address);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Writing port to {PortFile}", filename);
|
||||
logger.LogInformation("Writing port to {PortFile}", filename);
|
||||
using var tempFileStream = File.CreateText(filename);
|
||||
tempFileStream.Write(port.ToString());
|
||||
|
||||
@@ -67,24 +53,24 @@ public class PortWriterService : IHostedService
|
||||
await Task.Delay(5000);
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Deleting port file {PortFile}", filename);
|
||||
logger.LogInformation("Deleting port file {PortFile}", filename);
|
||||
File.Delete(filename);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Error while deleting port file {PortFile}", filename);
|
||||
logger.LogError(e, "Error while deleting port file {PortFile}", filename);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Could not save port to file");
|
||||
logger.LogError(ex, "Could not save port to file");
|
||||
}
|
||||
}
|
||||
|
||||
private string? GetAddress()
|
||||
{
|
||||
var features = _server.Features;
|
||||
var features = server.Features;
|
||||
var addresses = features.Get<IServerAddressesFeature>();
|
||||
var address = addresses?.Addresses.FirstOrDefault();
|
||||
return address;
|
||||
|
||||
@@ -5,37 +5,26 @@ using SharpCompress.Common;
|
||||
|
||||
namespace FileTime.Tools.Compression;
|
||||
|
||||
public class CompressOperation<TEntry, TVolume> : ICompressOperation
|
||||
public class CompressOperation<TEntry, TVolume>(IContentAccessorFactory contentAccessorFactory,
|
||||
AbstractWritableArchive<TEntry, TVolume> archive,
|
||||
Action<Stream> saveTo)
|
||||
: ICompressOperation
|
||||
where TEntry : IArchiveEntry
|
||||
where TVolume : IVolume
|
||||
{
|
||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||
private readonly AbstractWritableArchive<TEntry, TVolume> _archive;
|
||||
private readonly Action<Stream> _saveTo;
|
||||
private bool _disposed;
|
||||
|
||||
public CompressOperation(
|
||||
IContentAccessorFactory contentAccessorFactory,
|
||||
AbstractWritableArchive<TEntry, TVolume> archive,
|
||||
Action<Stream> saveTo
|
||||
)
|
||||
{
|
||||
_contentAccessorFactory = contentAccessorFactory;
|
||||
_archive = archive;
|
||||
_saveTo = saveTo;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<IDisposable>> CompressElement(IElement element, string key)
|
||||
{
|
||||
var contentReader = await _contentAccessorFactory.GetContentReaderFactory(element.Provider).CreateContentReaderAsync(element);
|
||||
var contentReader = await contentAccessorFactory.GetContentReaderFactory(element.Provider).CreateContentReaderAsync(element);
|
||||
var contentReaderStream = contentReader.GetStream();
|
||||
_archive.AddEntry(key, contentReaderStream);
|
||||
archive.AddEntry(key, contentReaderStream);
|
||||
|
||||
return new IDisposable[] {contentReader, contentReaderStream};
|
||||
}
|
||||
|
||||
public void SaveTo(Stream stream)
|
||||
=> _saveTo(stream);
|
||||
=> saveTo(stream);
|
||||
|
||||
~CompressOperation()
|
||||
{
|
||||
@@ -54,7 +43,7 @@ public class CompressOperation<TEntry, TVolume> : ICompressOperation
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_archive.Dispose();
|
||||
archive.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,31 +6,18 @@ using FileTime.Core.Timeline;
|
||||
|
||||
namespace FileTime.Tools.Compression.Compress;
|
||||
|
||||
public class CompressCommandFactory : ITransportationCommandFactory<CompressCommand>
|
||||
{
|
||||
private readonly IUserCommunicationService _userCommunicationService;
|
||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
|
||||
|
||||
public CompressCommandFactory(
|
||||
IUserCommunicationService userCommunicationService,
|
||||
public class CompressCommandFactory(IUserCommunicationService userCommunicationService,
|
||||
ITimelessContentProvider timelessContentProvider,
|
||||
IContentAccessorFactory contentAccessorFactory,
|
||||
ICommandSchedulerNotifier commandSchedulerNotifier)
|
||||
: ITransportationCommandFactory<CompressCommand>
|
||||
{
|
||||
_userCommunicationService = userCommunicationService;
|
||||
_timelessContentProvider = timelessContentProvider;
|
||||
_contentAccessorFactory = contentAccessorFactory;
|
||||
_commandSchedulerNotifier = commandSchedulerNotifier;
|
||||
}
|
||||
|
||||
public CompressCommand GenerateCommand(IReadOnlyCollection<FullName> sources, TransportMode mode, FullName targetFullName)
|
||||
=> new(
|
||||
_userCommunicationService,
|
||||
_timelessContentProvider,
|
||||
_contentAccessorFactory,
|
||||
_commandSchedulerNotifier,
|
||||
userCommunicationService,
|
||||
timelessContentProvider,
|
||||
contentAccessorFactory,
|
||||
commandSchedulerNotifier,
|
||||
sources,
|
||||
mode,
|
||||
targetFullName
|
||||
|
||||
@@ -5,24 +5,14 @@ using SharpCompress.Archives;
|
||||
|
||||
namespace FileTime.Tools.Compression.ContentProvider;
|
||||
|
||||
public sealed class CompressedContentProvider : SubContentProviderBase, ICompressedContentProvider
|
||||
{
|
||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||
|
||||
public CompressedContentProvider(
|
||||
ITimelessContentProvider timelessContentProvider,
|
||||
public sealed class CompressedContentProvider(ITimelessContentProvider timelessContentProvider,
|
||||
IContentAccessorFactory contentAccessorFactory,
|
||||
IContentProvider parentContentProvider
|
||||
)
|
||||
: base(
|
||||
timelessContentProvider,
|
||||
IContentProvider parentContentProvider)
|
||||
: SubContentProviderBase(timelessContentProvider,
|
||||
contentAccessorFactory,
|
||||
parentContentProvider,
|
||||
"compression")
|
||||
"compression"), ICompressedContentProvider
|
||||
{
|
||||
_timelessContentProvider = timelessContentProvider;
|
||||
}
|
||||
|
||||
public override async Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var parentElementContext = await GetParentElementReaderAsync(element);
|
||||
@@ -43,7 +33,7 @@ public sealed class CompressedContentProvider : SubContentProviderBase, ICompres
|
||||
|
||||
public override async ValueTask<VolumeSizeInfo?> GetVolumeSizeInfoAsync(FullName path)
|
||||
{
|
||||
var item = await GetItemByFullNameAsync(path, _timelessContentProvider.CurrentPointInTime.Value!);
|
||||
var item = await GetItemByFullNameAsync(path, timelessContentProvider.CurrentPointInTime.Value!);
|
||||
var parentElement = await GetParentElementAsync(item);
|
||||
return new VolumeSizeInfo(parentElement.Size, 0);
|
||||
}
|
||||
|
||||
@@ -3,19 +3,10 @@ using FileTime.Core.Timeline;
|
||||
|
||||
namespace FileTime.Tools.Compression.ContentProvider;
|
||||
|
||||
public sealed class CompressedContentProviderFactory : ICompressedContentProviderFactory
|
||||
{
|
||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||
|
||||
public CompressedContentProviderFactory(
|
||||
ITimelessContentProvider timelessContentProvider,
|
||||
public sealed class CompressedContentProviderFactory(ITimelessContentProvider timelessContentProvider,
|
||||
IContentAccessorFactory contentAccessorFactory)
|
||||
: ICompressedContentProviderFactory
|
||||
{
|
||||
_timelessContentProvider = timelessContentProvider;
|
||||
_contentAccessorFactory = contentAccessorFactory;
|
||||
}
|
||||
|
||||
public ICompressedContentProvider Create(IContentProvider parentContentProvider)
|
||||
=> new CompressedContentProvider(_timelessContentProvider, _contentAccessorFactory, parentContentProvider);
|
||||
=> new CompressedContentProvider(timelessContentProvider, contentAccessorFactory, parentContentProvider);
|
||||
}
|
||||
@@ -3,21 +3,14 @@ using SharpCompress.Archives;
|
||||
|
||||
namespace FileTime.Tools.Compression.ContentProvider;
|
||||
|
||||
public sealed class CompressedContentReader : IContentReader
|
||||
public sealed class CompressedContentReader(IArchiveEntry entry, IDisposable[] disposables) : IContentReader
|
||||
{
|
||||
private readonly IDisposable[] _disposables;
|
||||
private readonly Stream _stream;
|
||||
|
||||
public CompressedContentReader(IArchiveEntry entry, IDisposable[] disposables)
|
||||
{
|
||||
_disposables = disposables;
|
||||
_stream = entry.OpenEntryStream();
|
||||
}
|
||||
private readonly Stream _stream = entry.OpenEntryStream();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_stream.Dispose();
|
||||
foreach (var disposable in _disposables)
|
||||
foreach (var disposable in disposables)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
|
||||
@@ -4,13 +4,8 @@ using SharpCompress.Archives;
|
||||
|
||||
namespace FileTime.Tools.Compression.ContentProvider;
|
||||
|
||||
public sealed class CompressedContentReaderFactory : SubContentReaderBase<CompressedContentProvider>
|
||||
public sealed class CompressedContentReaderFactory(IContentAccessorFactory contentAccessorFactory) : SubContentReaderBase<CompressedContentProvider>(contentAccessorFactory)
|
||||
{
|
||||
|
||||
public CompressedContentReaderFactory(IContentAccessorFactory contentAccessorFactory)
|
||||
: base(contentAccessorFactory)
|
||||
{
|
||||
}
|
||||
public override async Task<IContentReader> CreateContentReaderAsync(IElement element)
|
||||
{
|
||||
if (element.Provider is not CompressedContentProvider provider)
|
||||
|
||||
@@ -8,25 +8,13 @@ using IContainer = FileTime.Core.Models.IContainer;
|
||||
|
||||
namespace FileTime.Tools.Compression.ContentProvider;
|
||||
|
||||
public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||
public sealed class CompressedSubContentProvider(IContentAccessorFactory contentAccessorFactory,
|
||||
ICompressedContentProviderFactory compressedContentProviderFactory,
|
||||
ITimelessContentProvider timelessContentProvider)
|
||||
: 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
|
||||
@@ -40,7 +28,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
||||
ItemInitializationSettings itemInitializationSettings = default)
|
||||
{
|
||||
var parentContentReader = await _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider).CreateContentReaderAsync(parentElement);
|
||||
var parentContentReader = await contentAccessorFactory.GetContentReaderFactory(parentElement.Provider).CreateContentReaderAsync(parentElement);
|
||||
var parentContentReaderStream = parentContentReader.GetStream();
|
||||
var archive = ArchiveFactory.Open(parentContentReaderStream);
|
||||
var disposables = new IDisposable[] {parentContentReader, parentContentReaderStream, archive};
|
||||
@@ -117,7 +105,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||
}
|
||||
|
||||
var parent = new AbsolutePath(
|
||||
_timelessContentProvider,
|
||||
timelessContentProvider,
|
||||
parentElement.PointInTime,
|
||||
childFullName.GetParent()!,
|
||||
AbsolutePathType.Container
|
||||
@@ -183,7 +171,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||
SupportsDelete.False,
|
||||
false,
|
||||
"",
|
||||
_compressedContentProviderFactory.Create(parentElement.Provider),
|
||||
compressedContentProviderFactory.Create(parentElement.Provider),
|
||||
false,
|
||||
parentElement.PointInTime,
|
||||
exceptions,
|
||||
@@ -246,7 +234,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||
addedContainers.Add(itemName);
|
||||
|
||||
children.Add(new AbsolutePath(
|
||||
_timelessContentProvider,
|
||||
timelessContentProvider,
|
||||
pointInTime,
|
||||
container.FullName.GetChild(itemName),
|
||||
AbsolutePathType.Container)
|
||||
@@ -256,7 +244,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||
{
|
||||
//Element
|
||||
children.Add(new AbsolutePath(
|
||||
_timelessContentProvider,
|
||||
timelessContentProvider,
|
||||
pointInTime,
|
||||
container.FullName.GetChild(itemName),
|
||||
AbsolutePathType.Element)
|
||||
@@ -290,7 +278,7 @@ public sealed class CompressedSubContentProvider : ICompressedSubContentProvider
|
||||
false,
|
||||
"",
|
||||
size,
|
||||
_compressedContentProviderFactory.Create(parentElement.Provider),
|
||||
compressedContentProviderFactory.Create(parentElement.Provider),
|
||||
parentElement.PointInTime,
|
||||
exceptions,
|
||||
new ReadOnlyExtensionCollection(new ExtensionCollection())
|
||||
|
||||
@@ -5,27 +5,16 @@ using FileTime.Core.Timeline;
|
||||
|
||||
namespace FileTime.Tools.Compression.Decompress;
|
||||
|
||||
public class DecompressCommandFactory : ITransportationCommandFactory<DecompressCommand>
|
||||
{
|
||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
|
||||
|
||||
public DecompressCommandFactory(
|
||||
ITimelessContentProvider timelessContentProvider,
|
||||
public class DecompressCommandFactory(ITimelessContentProvider timelessContentProvider,
|
||||
IContentAccessorFactory contentAccessorFactory,
|
||||
ICommandSchedulerNotifier commandSchedulerNotifier)
|
||||
: ITransportationCommandFactory<DecompressCommand>
|
||||
{
|
||||
_timelessContentProvider = timelessContentProvider;
|
||||
_contentAccessorFactory = contentAccessorFactory;
|
||||
_commandSchedulerNotifier = commandSchedulerNotifier;
|
||||
}
|
||||
|
||||
public DecompressCommand GenerateCommand(IReadOnlyCollection<FullName> sources, TransportMode mode, FullName targetFullName)
|
||||
=> new(
|
||||
_timelessContentProvider,
|
||||
_contentAccessorFactory,
|
||||
_commandSchedulerNotifier,
|
||||
timelessContentProvider,
|
||||
contentAccessorFactory,
|
||||
commandSchedulerNotifier,
|
||||
sources,
|
||||
mode,
|
||||
targetFullName);
|
||||
|
||||
@@ -5,24 +5,14 @@ using FileTime.Core.Timeline;
|
||||
|
||||
namespace FileTime.Tools.VirtualDiskSources;
|
||||
|
||||
public sealed class VirtualDiskContentProvider : SubContentProviderBase, IVirtualDiskContentProvider
|
||||
{
|
||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||
|
||||
public VirtualDiskContentProvider(
|
||||
ITimelessContentProvider timelessContentProvider,
|
||||
public sealed class VirtualDiskContentProvider(ITimelessContentProvider timelessContentProvider,
|
||||
IContentAccessorFactory contentAccessorFactory,
|
||||
IContentProvider parentContentProvider)
|
||||
: base(
|
||||
timelessContentProvider,
|
||||
: SubContentProviderBase(timelessContentProvider,
|
||||
contentAccessorFactory,
|
||||
parentContentProvider,
|
||||
"virtual-disk"
|
||||
)
|
||||
"virtual-disk"), IVirtualDiskContentProvider
|
||||
{
|
||||
_timelessContentProvider = timelessContentProvider;
|
||||
}
|
||||
|
||||
public override async Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var parentElementContext = await GetParentElementReaderAsync(element);
|
||||
@@ -44,7 +34,7 @@ public sealed class VirtualDiskContentProvider : SubContentProviderBase, IVirtua
|
||||
|
||||
public override async ValueTask<VolumeSizeInfo?> GetVolumeSizeInfoAsync(FullName path)
|
||||
{
|
||||
var item = await GetItemByFullNameAsync(path, _timelessContentProvider.CurrentPointInTime.Value!);
|
||||
var item = await GetItemByFullNameAsync(path, timelessContentProvider.CurrentPointInTime.Value!);
|
||||
var parentElement = await GetParentElementAsync(item);
|
||||
return new VolumeSizeInfo(parentElement.Size, 0);
|
||||
}
|
||||
|
||||
@@ -3,19 +3,10 @@ using FileTime.Core.Timeline;
|
||||
|
||||
namespace FileTime.Tools.VirtualDiskSources;
|
||||
|
||||
public sealed class VirtualDiskContentProviderFactory : IVirtualDiskContentProviderFactory
|
||||
{
|
||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||
|
||||
public VirtualDiskContentProviderFactory(
|
||||
ITimelessContentProvider timelessContentProvider,
|
||||
public sealed class VirtualDiskContentProviderFactory(ITimelessContentProvider timelessContentProvider,
|
||||
IContentAccessorFactory contentAccessorFactory)
|
||||
: IVirtualDiskContentProviderFactory
|
||||
{
|
||||
_timelessContentProvider = timelessContentProvider;
|
||||
_contentAccessorFactory = contentAccessorFactory;
|
||||
}
|
||||
|
||||
public IVirtualDiskContentProvider Create(IContentProvider parentContentProvider)
|
||||
=> new VirtualDiskContentProvider(_timelessContentProvider, _contentAccessorFactory, parentContentProvider);
|
||||
=> new VirtualDiskContentProvider(timelessContentProvider, contentAccessorFactory, parentContentProvider);
|
||||
}
|
||||
@@ -2,23 +2,14 @@
|
||||
|
||||
namespace FileTime.Tools.VirtualDiskSources;
|
||||
|
||||
public sealed class VirtualDiskContentReader : IContentReader
|
||||
public sealed class VirtualDiskContentReader(Stream stream, ICollection<IDisposable> disposables) : IContentReader
|
||||
{
|
||||
private readonly Stream _stream;
|
||||
private readonly ICollection<IDisposable> _disposables;
|
||||
|
||||
public VirtualDiskContentReader(Stream stream, ICollection<IDisposable> disposables)
|
||||
{
|
||||
_stream = stream;
|
||||
_disposables = disposables;
|
||||
}
|
||||
|
||||
public Stream GetStream() => _stream;
|
||||
public Stream GetStream() => stream;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_stream.Dispose();
|
||||
foreach (var disposable in _disposables)
|
||||
stream.Dispose();
|
||||
foreach (var disposable in disposables)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
|
||||
@@ -4,13 +4,8 @@ using FileTime.Core.Models;
|
||||
|
||||
namespace FileTime.Tools.VirtualDiskSources;
|
||||
|
||||
public sealed class VirtualDiskContentReaderFactory : SubContentReaderBase<VirtualDiskContentProvider>
|
||||
public sealed class VirtualDiskContentReaderFactory(IContentAccessorFactory contentAccessorFactory) : SubContentReaderBase<VirtualDiskContentProvider>(contentAccessorFactory)
|
||||
{
|
||||
public VirtualDiskContentReaderFactory(IContentAccessorFactory contentAccessorFactory)
|
||||
: base(contentAccessorFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<IContentReader> CreateContentReaderAsync(IElement element)
|
||||
{
|
||||
if (element.Provider is not VirtualDiskContentProvider provider)
|
||||
|
||||
@@ -8,23 +8,11 @@ using FileTime.Core.Timeline;
|
||||
|
||||
namespace FileTime.Tools.VirtualDiskSources;
|
||||
|
||||
public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvider
|
||||
{
|
||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||
private readonly IVirtualDiskContentProviderFactory _virtualDiskContentProviderFactory;
|
||||
|
||||
public VirtualDiskSubContentProvider(
|
||||
IContentAccessorFactory contentAccessorFactory,
|
||||
public sealed class VirtualDiskSubContentProvider(IContentAccessorFactory contentAccessorFactory,
|
||||
ITimelessContentProvider timelessContentProvider,
|
||||
IVirtualDiskContentProviderFactory virtualDiskContentProviderFactory
|
||||
)
|
||||
IVirtualDiskContentProviderFactory virtualDiskContentProviderFactory)
|
||||
: IVirtualDiskSubContentProvider
|
||||
{
|
||||
_contentAccessorFactory = contentAccessorFactory;
|
||||
_timelessContentProvider = timelessContentProvider;
|
||||
_virtualDiskContentProviderFactory = virtualDiskContentProviderFactory;
|
||||
}
|
||||
|
||||
public Task<bool> CanHandleAsync(IElement parentElement)
|
||||
=> Task.FromResult(parentElement.NativePath?.Path.EndsWith(".iso", StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
|
||||
@@ -35,7 +23,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
|
||||
AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown,
|
||||
ItemInitializationSettings itemInitializationSettings = default)
|
||||
{
|
||||
var contentReaderFactory = _contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
|
||||
var contentReaderFactory = contentAccessorFactory.GetContentReaderFactory(parentElement.Provider);
|
||||
var reader = await contentReaderFactory.CreateContentReaderAsync(parentElement);
|
||||
|
||||
await using var readerStream = reader.GetStream();
|
||||
@@ -80,7 +68,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
|
||||
var childNativePath = new NativePath(childNativePathBase);
|
||||
|
||||
var parent = new AbsolutePath(
|
||||
_timelessContentProvider,
|
||||
timelessContentProvider,
|
||||
pointInTime,
|
||||
childFullName.GetParent()!,
|
||||
AbsolutePathType.Container
|
||||
@@ -152,7 +140,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
|
||||
SupportsDelete.False,
|
||||
false,
|
||||
FormatAttributes(sourceContainer.Attributes),
|
||||
_virtualDiskContentProviderFactory.Create(parentContentProvider),
|
||||
virtualDiskContentProviderFactory.Create(parentContentProvider),
|
||||
false,
|
||||
pointInTime,
|
||||
exceptions,
|
||||
@@ -191,7 +179,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
|
||||
foreach (var discDirectoryInfo in sourceContainer.GetDirectories())
|
||||
{
|
||||
children.Add(new AbsolutePath(
|
||||
_timelessContentProvider,
|
||||
timelessContentProvider,
|
||||
pointInTime,
|
||||
container.FullName.GetChild(discDirectoryInfo.Name),
|
||||
AbsolutePathType.Container)
|
||||
@@ -201,7 +189,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
|
||||
foreach (var fileInfo in sourceContainer.GetFiles())
|
||||
{
|
||||
children.Add(new AbsolutePath(
|
||||
_timelessContentProvider,
|
||||
timelessContentProvider,
|
||||
pointInTime,
|
||||
container.FullName.GetChild(fileInfo.Name),
|
||||
AbsolutePathType.Element)
|
||||
@@ -230,7 +218,7 @@ public sealed class VirtualDiskSubContentProvider : IVirtualDiskSubContentProvid
|
||||
false,
|
||||
FormatAttributes(childElement.Attributes),
|
||||
childElement.Length,
|
||||
_virtualDiskContentProviderFactory.Create(parentContentProvider),
|
||||
virtualDiskContentProviderFactory.Create(parentContentProvider),
|
||||
pointInTime,
|
||||
new ObservableCollection<Exception>(),
|
||||
new ReadOnlyExtensionCollection(new ExtensionCollection())
|
||||
|
||||
Reference in New Issue
Block a user