// Copyright (c) StellaOps. All rights reserved.
// Licensed under AGPL-3.0-or-later. See LICENSE in the project root.
using Microsoft.Extensions.Logging;
namespace StellaOps.BinaryIndex.Disassembly;
///
/// Default implementation of the disassembly plugin registry.
///
public sealed class DisassemblyPluginRegistry : IDisassemblyPluginRegistry
{
private readonly ILogger _logger;
private readonly List _plugins;
///
/// Creates a new plugin registry with the given plugins.
///
/// The registered plugins.
/// Logger instance.
public DisassemblyPluginRegistry(
IEnumerable plugins,
ILogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_plugins = (plugins ?? throw new ArgumentNullException(nameof(plugins)))
.OrderByDescending(p => p.Capabilities.Priority)
.ToList();
_logger.LogInformation(
"Disassembly plugin registry initialized with {Count} plugins: {Plugins}",
_plugins.Count,
string.Join(", ", _plugins.Select(p => p.Capabilities.PluginId)));
}
///
public IReadOnlyList Plugins => _plugins;
///
public IDisassemblyPlugin? FindPlugin(CpuArchitecture architecture, BinaryFormat format)
{
var plugin = _plugins.FirstOrDefault(p => p.Capabilities.CanHandle(architecture, format));
if (plugin != null)
{
_logger.LogDebug(
"Selected plugin {Plugin} for architecture {Arch} and format {Format}",
plugin.Capabilities.PluginId, architecture, format);
}
else
{
_logger.LogWarning(
"No plugin found for architecture {Arch} and format {Format}",
architecture, format);
}
return plugin;
}
///
public IEnumerable FindPluginsForArchitecture(CpuArchitecture architecture)
{
return _plugins.Where(p => p.Capabilities.SupportsArchitecture(architecture));
}
///
public IEnumerable FindPluginsForFormat(BinaryFormat format)
{
return _plugins.Where(p => p.Capabilities.SupportsFormat(format));
}
///
public IDisassemblyPlugin? GetPlugin(string pluginId)
{
return _plugins.FirstOrDefault(p =>
p.Capabilities.PluginId.Equals(pluginId, StringComparison.OrdinalIgnoreCase));
}
}