6 changed files with 258 additions and 70 deletions
@ -0,0 +1,129 @@ |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Avalonia.Utilities; |
|||
using Mono.Cecil; |
|||
|
|||
namespace Avalonia.Build.Tasks |
|||
{ |
|||
public static partial class XamlCompilerTaskExecutor |
|||
{ |
|||
interface IResource |
|||
{ |
|||
string Uri { get; } |
|||
string Name { get; } |
|||
byte[] GetData(); |
|||
string FilePath { get; } |
|||
void Remove(); |
|||
|
|||
} |
|||
|
|||
interface IResourceGroup |
|||
{ |
|||
string Name { get; } |
|||
IEnumerable<IResource> Resources { get; } |
|||
} |
|||
|
|||
class EmbeddedResources : IResourceGroup |
|||
{ |
|||
private readonly AssemblyDefinition _asm; |
|||
public string Name => "EmbeddedResource"; |
|||
|
|||
public IEnumerable<IResource> Resources => _asm.MainModule.Resources.OfType<EmbeddedResource>() |
|||
.Select(r => new WrappedResource(_asm, r)).ToList(); |
|||
|
|||
public EmbeddedResources(AssemblyDefinition asm) |
|||
{ |
|||
_asm = asm; |
|||
} |
|||
class WrappedResource : IResource |
|||
{ |
|||
private readonly AssemblyDefinition _asm; |
|||
private readonly EmbeddedResource _res; |
|||
|
|||
public WrappedResource(AssemblyDefinition asm, EmbeddedResource res) |
|||
{ |
|||
_asm = asm; |
|||
_res = res; |
|||
} |
|||
|
|||
public string Uri => $"resm:{Name}?assembly={_asm.Name}"; |
|||
public string Name => _res.Name; |
|||
public byte[] GetData() => _res.GetResourceData(); |
|||
public string FilePath => Name; |
|||
|
|||
public void Remove() => _asm.MainModule.Resources.Remove(_res); |
|||
} |
|||
} |
|||
|
|||
class AvaloniaResources : IResourceGroup |
|||
{ |
|||
private readonly AssemblyDefinition _asm; |
|||
Dictionary<string, AvaloniaResource> _resources = new Dictionary<string, AvaloniaResource>(); |
|||
private EmbeddedResource _embedded; |
|||
public AvaloniaResources(AssemblyDefinition asm, string projectDir) |
|||
{ |
|||
_asm = asm; |
|||
_embedded = ((EmbeddedResource)asm.MainModule.Resources.FirstOrDefault(r => |
|||
r.ResourceType == ResourceType.Embedded && r.Name == "!AvaloniaResources")); |
|||
if (_embedded == null) |
|||
return; |
|||
using (var stream = _embedded.GetResourceStream()) |
|||
{ |
|||
var br = new BinaryReader(stream); |
|||
var index = AvaloniaResourcesIndexReaderWriter.Read(new MemoryStream(br.ReadBytes(br.ReadInt32()))); |
|||
var baseOffset = stream.Position; |
|||
foreach (var e in index) |
|||
{ |
|||
stream.Position = e.Offset + baseOffset; |
|||
_resources[e.Path] = new AvaloniaResource(this, projectDir, e.Path, br.ReadBytes(e.Size)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void Save() |
|||
{ |
|||
if (_embedded != null) |
|||
{ |
|||
_asm.MainModule.Resources.Remove(_embedded); |
|||
_embedded = null; |
|||
} |
|||
|
|||
if (_resources.Count == 0) |
|||
return; |
|||
|
|||
_embedded = new EmbeddedResource("!AvaloniaResources", ManifestResourceAttributes.Public, |
|||
AvaloniaResourcesIndexReaderWriter.Create(_resources.ToDictionary(x => x.Key, |
|||
x => x.Value.GetData()))); |
|||
_asm.MainModule.Resources.Add(_embedded); |
|||
} |
|||
|
|||
public string Name => "AvaloniaResources"; |
|||
public IEnumerable<IResource> Resources => _resources.Values.ToList(); |
|||
|
|||
class AvaloniaResource : IResource |
|||
{ |
|||
private readonly AvaloniaResources _grp; |
|||
private readonly byte[] _data; |
|||
|
|||
public AvaloniaResource(AvaloniaResources grp, |
|||
string projectDir, |
|||
string name, byte[] data) |
|||
{ |
|||
_grp = grp; |
|||
_data = data; |
|||
Name = name; |
|||
FilePath = Path.Combine(projectDir, name.TrimStart('/')); |
|||
Uri = $"avares://{grp._asm.Name}/{name.TrimStart('/')}"; |
|||
} |
|||
public string Uri { get; } |
|||
public string Name { get; } |
|||
public byte[] GetData() => _data; |
|||
public string FilePath { get; } |
|||
|
|||
public void Remove() => _grp._resources.Remove(Name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -1 +1 @@ |
|||
Subproject commit 2c9c9cb392d36af4624578254aa376ef0bb5a964 |
|||
Subproject commit c28bd89bf4c315c188394139f500f7f4efed4b94 |
|||
Loading…
Reference in new issue