Skip to content

Commit 9665c61

Browse files
committed
Updates
1 parent a189726 commit 9665c61

File tree

19 files changed

+546
-373
lines changed

19 files changed

+546
-373
lines changed

src/MobilePackageGen.Common/RemakeAppx/Helpers/IODir.cs

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/MobilePackageGen.Common/RemakeAppx/Helpers/IOFile.cs

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/MobilePackageGen.Common/RemakeAppx/Program.cs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
using System.IO.Abstractions;
2-
using System.Reactive.Linq;
3-
using CSharpFunctionalExtensions;
1+
using CSharpFunctionalExtensions;
42
using DotnetPackaging.Msix;
5-
using Zafiro.DivineBytes;
63
using Serilog;
7-
using RemakeAppx.Helpers;
4+
using System.IO.Abstractions;
5+
using Zafiro.DivineBytes;
6+
using Zafiro.DivineBytes.System.IO;
87
using File = System.IO.File;
98

109
namespace RemakeAppx
@@ -13,19 +12,15 @@ public class Program
1312
{
1413
public static async Task MakeAppx(string inputFolder, string outputFile, bool bundleMode, bool unsignedMode)
1514
{
16-
/*Console.WriteLine($"Making {outputFile} out of {inputFolder}");
17-
Console.WriteLine($"Bundle Mode: {bundleMode}");
18-
Console.WriteLine($"Unsigned Mode: {unsignedMode}");*/
19-
2015
FileSystem fs = new();
21-
IDirectoryInfo directoryInfo = fs.DirectoryInfo.New(inputFolder);
22-
IODir ioDir = new(directoryInfo);
16+
var directoryInfo = fs.DirectoryInfo.New(inputFolder);
17+
var directoryContainer = new DirectoryContainer(directoryInfo);
2318

24-
await Msix.FromDirectory(ioDir, Maybe<ILogger>.None, bundleMode, unsignedMode, inputFolder)
19+
await Msix.FromDirectory(directoryContainer, Maybe<ILogger>.None, bundleMode, unsignedMode, inputFolder)
2520
.Map(async source =>
2621
{
2722
await using var fileStream = File.Open(outputFile, FileMode.Create);
28-
return await source.DumpTo(fileStream);
23+
return await source.WriteTo(fileStream);
2924
});
3025
}
3126
}

thirdparty/DeflateBlockCompressor/Compressed.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public static class Compressed
1818
/// </summary>
1919
public static IObservable<DeflateBlock> Blocks(
2020
IObservable<byte[]> input,
21-
int compressionLevel = ZLib.Z_BEST_COMPRESSION,
21+
int compressionLevel = 6,
2222
int uncompressedBlockSize = DefaultBlockSize)
2323
{
2424
return Observable.Create<DeflateBlock>(observer =>

thirdparty/DeflateBlockCompressor/ZStreamWrapper.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ internal class ZStreamWrapper
3232

3333
// ZLib instance
3434
private readonly ZLib zlib = new ZLib();
35-
35+
3636
/// <summary>
3737
/// Compresses the specified input bytes using DEFLATE algorithm.
3838
/// </summary>
3939
/// <param name="input">The byte array to compress.</param>
4040
/// <param name="compressionLevel">The compression level to use, defaults to best compression.</param>
4141
/// <returns>A new byte array containing the compressed data.</returns>
4242
/// <exception cref="InvalidOperationException">Thrown when ZLib initialization fails.</exception>
43-
public byte[] Deflate(byte[] input, int compressionLevel = ZLib.Z_BEST_COMPRESSION)
43+
public byte[] Deflate(byte[] input, int compressionLevel = 6)
4444
{
4545
// Estimation of the maximum possible size for compressed data
4646
uint compressedSizeEstimate = (uint)input.Length +
@@ -107,7 +107,7 @@ private void DeflateInternal(byte[] input, byte[] output, int compressionLevel)
107107
compressionLevel,
108108
ZLib.Z_DEFLATED,
109109
-15, // Negative for raw deflate (no header/trailer)
110-
9, // MAX_MEM_LEVEL = 9
110+
8, // MAX_MEM_LEVEL = 9
111111
ZLib.Z_DEFAULT_STRATEGY);
112112

113113
if (LastResult != ZLib.Z_OK)

thirdparty/DotnetPackaging.Msix/Core/Compression/Compressor.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,40 @@ public static class Compressor
99
{
1010
public static async Task<byte[]> Uncompress(byte[] compressedData)
1111
{
12-
using (MemoryStream ms = new MemoryStream(compressedData))
12+
using (MemoryStream ms = new(compressedData))
1313
{
14-
await using (DeflateStream deflate = new DeflateStream(ms, CompressionMode.Decompress))
14+
await using (DeflateStream deflate = new(ms, CompressionMode.Decompress))
1515
{
16-
using (MemoryStream output = new MemoryStream())
16+
using (MemoryStream output = new())
1717
{
1818
await deflate.CopyToAsync(output);
1919
return output.ToArray();
2020
}
2121
}
2222
}
2323
}
24-
24+
2525
public static IObservable<byte[]> Compressed(this IObservable<byte[]> source, CompressionLevel compressionLevel = CompressionLevel.Optimal)
2626
{
2727
return Observable.Create<byte[]>(observer =>
2828
{
29-
// Aumentar el tamaño del buffer para evitar bloqueos
30-
PipeOptions pipeOptions = new PipeOptions(pauseWriterThreshold: 1024 * 1024); // 1MB
31-
Pipe pipe = new Pipe(pipeOptions);
29+
// Increase buffer size to avoid blocking
30+
PipeOptions pipeOptions = new(pauseWriterThreshold: 1024 * 1024); // 1MB
31+
Pipe pipe = new(pipeOptions);
3232

33-
// Primero configurar la suscripción de lectura para asegurar que se consumen los datos
33+
// First configure the read subscription to ensure data is consumed
3434
IDisposable readSubscription = pipe.Reader.AsStream().ToObservable().Subscribe(observer);
3535

36-
// Crear el DeflateStream después de configurar la lectura
37-
DeflateStream deflateStream = new DeflateStream(pipe.Writer.AsStream(), compressionLevel, leaveOpen: true);
36+
// Create DeflateStream after configuring the read
37+
DeflateStream deflateStream = new(pipe.Writer.AsStream(), compressionLevel, leaveOpen: true);
3838

3939
// Suscribirse a la fuente
4040
IDisposable subscription = source.Subscribe(
4141
block =>
4242
{
4343
try
4444
{
45-
var array = block.ToArray();
45+
byte[] array = block.ToArray();
4646
deflateStream.Write(array, 0, array.Length);
4747
deflateStream.Flush(); // Hacer flush del DeflateStream
4848
pipe.Writer.FlushAsync().GetAwaiter().GetResult(); // Hacer flush del PipeWriter
@@ -76,7 +76,7 @@ public static IObservable<byte[]> Compressed(this IObservable<byte[]> source, Co
7676
{
7777
try
7878
{
79-
deflateStream.Close();
79+
deflateStream.Close();
8080
pipe.Writer.Complete();
8181
}
8282
catch (Exception ex)

thirdparty/DotnetPackaging.Msix/Core/Compression/Extensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ namespace DotnetPackaging.Msix.Core.Compression;
55
public static class Extensions
66
{
77
public static IObservable<byte[]> ReadMyBytes(this Stream stream, long offset, int tamaño)
8-
{
8+
{
99
// Posicionamos el stream en el offset indicado.
1010
stream.Seek(offset, SeekOrigin.Begin);
1111

1212
return Observable.Create<byte[]>(observer =>
1313
{
1414
// Creamos un token para poder cancelar la lectura en caso de desuscripción.
15-
CancellationTokenSource cts = new CancellationTokenSource();
15+
CancellationTokenSource cts = new();
1616

1717
// Función recursiva asíncrona que realiza la lectura.
1818
Func<Task> leerRecursivamente = null;
@@ -23,7 +23,7 @@ public static IObservable<byte[]> ReadMyBytes(this Stream stream, long offset, i
2323
// Si se solicita cancelar, se sale.
2424
cts.Token.ThrowIfCancellationRequested();
2525

26-
var buffer = new byte[tamaño];
26+
byte[] buffer = new byte[tamaño];
2727
int bytesLeidos = await stream.Leer(buffer, 0, tamaño).ConfigureAwait(false);
2828
if (bytesLeidos == 0)
2929
{

thirdparty/DotnetPackaging.Msix/Core/Compression/ObservableStream.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public ObservableStream(IObserver<byte[]> observer)
1212
public override void Write(byte[] buffer, int offset, int count)
1313
{
1414
// Copiamos los bytes escritos y los enviamos directamente al observer.
15-
var chunk = new byte[count];
15+
byte[] chunk = new byte[count];
1616
Array.Copy(buffer, offset, chunk, 0, count);
1717
_observer.OnNext(chunk);
1818
}

thirdparty/DotnetPackaging.Msix/Core/ContentTypes/ContentTypesGenerator.cs

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
namespace DotnetPackaging.Msix.Core.ContentTypes;
44

55
/// <summary>
6-
/// Generador de Content Types que, a partir de la colección de nombres de partes,
7-
/// construye un modelo inmutable con las entradas Default y Override.
6+
/// Genera el modelo de tipos de contenido ([Content_Types].xml) emulando el comportamiento de makeappx.
87
/// </summary>
98
public static class ContentTypesGenerator
109
{
@@ -100,7 +99,7 @@ public static class ContentTypesGenerator
10099
{ "xsl", "application/xslt+xml" },
101100
{ "xslt", "application/xslt+xml" },
102101
{ "zip", "application/x-zip-compressed" },
103-
// Puedes agregar más según sea necesario.
102+
// Puedes agregar más según sea necesario.
104103
};
105104

106105

@@ -196,13 +195,13 @@ public static class ContentTypesGenerator
196195
{ "xsl", "application/xslt+xml" },
197196
{ "xslt", "application/xslt+xml" },
198197
{ "zip", "application/x-zip-compressed" },
199-
// Puedes agregar más según sea necesario.
198+
// Puedes agregar más según sea necesario.
200199
};
201200

202201
// Diccionario de overrides predefinidos para partes conocidas.
203202
private static readonly Dictionary<string, string> OverrideMappings = new(StringComparer.OrdinalIgnoreCase)
204203
{
205-
// Si se incluye el manifiesto, se puede generar como override o default, según la estrategia.
204+
// Si se incluye el manifiesto, se puede generar como override o default, según la estrategia.
206205
// En el ejemplo de makeappx se trata a AppxManifest.xml como un archivo con default (al final aparece en el block map),
207206
// pero para [Content_Types].xml se suele definir override para el block map.
208207
{ "/AppxBlockMap.xml", "application/vnd.ms-appx.blockmap+xml" },
@@ -211,64 +210,63 @@ public static class ContentTypesGenerator
211210
// Puedes agregar otros overrides si es necesario.
212211
};
213212

214-
/// <summary>
215-
/// Genera un modelo inmutable de ContentTypesModel a partir de una colección de nombres de partes del paquete.
216-
/// Se agregan entradas Default basadas en la extensión y se añaden overrides para nombres conocidos.
217-
/// </summary>
218-
/// <param name="partNames">Colección de nombres de partes (por ejemplo, "folder/file.ext").</param>
219-
/// <returns>ContentTypesModel inmutable.</returns>
220213
public static ContentTypesModel Create(IEnumerable<string> partNames, bool bundleMode)
221214
{
222215
if (partNames == null)
223216
throw new ArgumentNullException(nameof(partNames));
224217

225-
ImmutableDictionary<string, string>.Builder defaultsBuilder = ImmutableDictionary.CreateBuilder<string, string>(StringComparer.OrdinalIgnoreCase);
226-
ImmutableList<OverrideContentType>.Builder overridesBuilder = ImmutableList.CreateBuilder<OverrideContentType>();
218+
List<DefaultContentType> defaults = [];
219+
List<OverrideContentType> overrides = [];
220+
HashSet<string> seenExtensions = new(StringComparer.OrdinalIgnoreCase);
221+
HashSet<string> seenOverrides = new(StringComparer.OrdinalIgnoreCase);
227222

228-
foreach (var part in partNames)
223+
foreach (string part in partNames)
229224
{
230-
// Normalizamos el nombre: aseguramos que empiece con "/" y reemplazamos '\' por '/'.
231-
string normalizedPart = part.StartsWith("/") ? part : "/" + part.Replace('\\', '/');
225+
string normalizedPart = NormalizePartName(part);
232226

233-
// Si el nombre coincide con algún override predefinido, lo agregamos.
234-
if (OverrideMappings.TryGetValue(normalizedPart, out var overrideContentType))
227+
if (OverrideMappings.TryGetValue(normalizedPart, out string? overrideContentType))
235228
{
236-
overridesBuilder.Add(new OverrideContentType(normalizedPart, overrideContentType));
229+
if (seenOverrides.Add(normalizedPart))
230+
{
231+
overrides.Add(new OverrideContentType(normalizedPart, overrideContentType));
232+
}
233+
234+
continue;
237235
}
238-
else
236+
237+
string extension = GetExtension(part);
238+
if (!string.IsNullOrEmpty(extension))
239239
{
240-
// Extraemos la extensión del archivo.
241-
string extension = GetExtension(part);
242-
if (!string.IsNullOrEmpty(extension))
240+
if (seenExtensions.Add(extension))
243241
{
244-
if (!defaultsBuilder.ContainsKey(extension))
242+
if (bundleMode ? !DefaultMappingsForBundles.TryGetValue(extension, out var contentType) : !DefaultMappings.TryGetValue(extension, out contentType))
245243
{
246-
if (bundleMode ? !DefaultMappingsForBundles.TryGetValue(extension, out var contentType) : !DefaultMappings.TryGetValue(extension, out contentType))
247-
contentType = "application/octet-stream";
248-
defaultsBuilder.Add(extension, contentType);
244+
contentType = "application/octet-stream";
249245
}
246+
247+
defaults.Add(new DefaultContentType(extension, contentType));
250248
}
251-
else
252-
{
253-
// Si no hay extensión, tratamos la parte como override.
254-
overridesBuilder.Add(new OverrideContentType(normalizedPart, "application/octet-stream"));
255-
}
249+
250+
continue;
251+
}
252+
253+
if (seenOverrides.Add(normalizedPart))
254+
{
255+
overrides.Add(new OverrideContentType(normalizedPart, "application/octet-stream"));
256256
}
257257
}
258258

259-
ImmutableList<DefaultContentType> defaultsList = defaultsBuilder.Select(kvp => new DefaultContentType(kvp.Key, kvp.Value))
260-
.ToImmutableList();
261-
ImmutableList<OverrideContentType> overridesList = overridesBuilder.ToImmutableList();
259+
return new ContentTypesModel(defaults.ToImmutableList(), overrides.ToImmutableList());
260+
}
262261

263-
return new ContentTypesModel(defaultsList, overridesList);
262+
private static string NormalizePartName(string part)
263+
{
264+
return part.StartsWith("/") ? part : "/" + part.Replace('\\', '/');
264265
}
265266

266267
private static string GetExtension(string partName)
267268
{
268-
// Extrae la extensión utilizando Path.GetExtension y remueve el punto.
269269
string ext = Path.GetExtension(partName);
270-
if (!string.IsNullOrEmpty(ext))
271-
return ext.TrimStart('.').ToLowerInvariant();
272-
return string.Empty;
270+
return string.IsNullOrEmpty(ext) ? string.Empty : ext.TrimStart('.').ToLowerInvariant();
273271
}
274272
}

thirdparty/DotnetPackaging.Msix/Core/ContentTypes/ContentTypesSerializer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
namespace DotnetPackaging.Msix.Core.ContentTypes;
66

77
/// <summary>
8-
/// Serializador del modelo de Content Types a XML, generando un [Content_Types].xml conforme a la especificación.
8+
/// Serializador del modelo de Content Types a XML, generando un [Content_Types].xml conforme a la especificación.
99
/// </summary>
1010
public static class ContentTypesSerializer
1111
{
1212
/// <summary>
1313
/// Serializa el ContentTypesModel a un string XML.
1414
/// </summary>
1515
/// <param name="model">Modelo de content types.</param>
16-
/// <returns>XML en formato string con la declaración UTF-8.</returns>
16+
/// <returns>XML en formato string con la declaración UTF-8.</returns>
1717
public static string Serialize(ContentTypesModel model)
1818
{
1919
XNamespace ns = "http://schemas.openxmlformats.org/package/2006/content-types";

0 commit comments

Comments
 (0)