Merge pull request #717 from ds5678/lzma-improvements

Several improvements to the LZMA Compressor
This commit is contained in:
Adam Hathcock
2022-12-23 10:24:24 +00:00
committed by GitHub
5 changed files with 69 additions and 7 deletions

View File

@@ -150,7 +150,7 @@ internal enum CoderPropId
internal interface ISetCoderProperties
{
void SetCoderProperties(CoderPropId[] propIDs, object[] properties);
void SetCoderProperties(ReadOnlySpan<CoderPropId> propIDs, ReadOnlySpan<object> properties);
}
internal interface IWriteCoderProperties

View File

@@ -1725,9 +1725,9 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
return -1;
}
public void SetCoderProperties(CoderPropId[] propIDs, object[] properties)
public void SetCoderProperties(ReadOnlySpan<CoderPropId> propIDs, ReadOnlySpan<object> properties)
{
for (uint i = 0; i < properties.Length; i++)
for (int i = 0; i < properties.Length; i++)
{
var prop = properties[i];
switch (propIDs[i])

View File

@@ -1,9 +1,16 @@
using System;
namespace SharpCompress.Compressors.LZMA;
public class LzmaEncoderProperties
{
internal CoderPropId[] _propIDs;
internal object[] _properties;
public static LzmaEncoderProperties Default { get; } = new();
internal ReadOnlySpan<CoderPropId> PropIDs => _propIDs;
private readonly CoderPropId[] _propIDs;
internal ReadOnlySpan<object> Properties => _properties;
private readonly object[] _properties;
public LzmaEncoderProperties() : this(false) { }

View File

@@ -1,4 +1,4 @@
#nullable disable
#nullable disable
using System;
using System.Buffers.Binary;
@@ -111,7 +111,7 @@ public class LzmaStream : Stream
}
_encoder = new Encoder();
_encoder.SetCoderProperties(properties._propIDs, properties._properties);
_encoder.SetCoderProperties(properties.PropIDs, properties.Properties);
var prop = new byte[5];
_encoder.WriteCoderProperties(prop);
Properties = prop;

View File

@@ -1,4 +1,6 @@
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.IO;
using SharpCompress.Compressors.LZMA;
using Xunit;
@@ -177,6 +179,9 @@ public class LzmaStreamTests
0x90
};
/// <summary>
/// The decoded data for <see cref="lzmaData"/>.
/// </summary>
private static byte[] lzmaResultData { get; } =
new byte[]
{
@@ -528,4 +533,54 @@ public class LzmaStreamTests
Assert.Equal(output.ToArray(), lzmaResultData);
}
[Fact]
public void TestLzmaStreamEncodingWritesData()
{
using MemoryStream inputStream = new MemoryStream(lzmaResultData);
using MemoryStream outputStream = new();
using LzmaStream lzmaStream = new LzmaStream(LzmaEncoderProperties.Default, false, outputStream);
inputStream.CopyTo(lzmaStream);
lzmaStream.Close();
Assert.NotEqual(0, outputStream.Length);
}
[Fact]
public void TestLzmaEncodingAccuracy()
{
var input = new MemoryStream(lzmaResultData);
var compressed = new MemoryStream();
LzmaStream lzmaEncodingStream = new LzmaStream(LzmaEncoderProperties.Default, false, compressed);
input.CopyTo(lzmaEncodingStream);
lzmaEncodingStream.Close();
compressed.Position = 0;
var output = new MemoryStream();
DecompressLzmaStream(lzmaEncodingStream.Properties, compressed, compressed.Length, output, lzmaResultData.LongLength);
Assert.Equal(output.ToArray(), lzmaResultData);
}
private static void DecompressLzmaStream(byte[] properties, Stream compressedStream, long compressedSize, Stream decompressedStream, long decompressedSize)
{
LzmaStream lzmaStream = new LzmaStream(properties, compressedStream, compressedSize, -1, null, false);
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);
long totalRead = 0;
while (totalRead < decompressedSize)
{
int toRead = (int)Math.Min(buffer.Length, decompressedSize - totalRead);
int read = lzmaStream.Read(buffer, 0, toRead);
if (read > 0)
{
decompressedStream.Write(buffer, 0, read);
totalRead += read;
}
else
{
break;
}
}
ArrayPool<byte>.Shared.Return(buffer);
}
}