1
0

Fix GZippedString decompress

This commit is contained in:
Mike Schwörer 2023-11-12 18:52:29 +01:00
parent a274c5eaf3
commit 5228f3e840
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
2 changed files with 34 additions and 10 deletions

View File

@ -6,4 +6,16 @@ public static class Extensions
{ {
Console.Out.WriteLine(str); Console.Out.WriteLine(str);
} }
public static byte[] ReadAllToByteArray(this Stream stream)
{
var bytes = new List<byte>();
int b;
// -1 is a special value that mark the end of the stream
while ((b = stream.ReadByte()) != -1) bytes.Add((byte)b);
return bytes.ToArray();
}
} }

View File

@ -24,31 +24,43 @@ public class GZippedString : IXmlSerializable
private string CompressString(string text) private string CompressString(string text)
{ {
byte[] buffer = Encoding.UTF8.GetBytes(text); byte[] buffer = Encoding.UTF8.GetBytes(text);
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true)) using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
gZipStream.Write(buffer, 0, buffer.Length); gZipStream.Write(buffer, 0, buffer.Length);
memoryStream.Position = 0; memoryStream.Position = 0;
var compressedData = new byte[memoryStream.Length]; var compressedData = new byte[memoryStream.Length];
memoryStream.Read(compressedData, 0, compressedData.Length); memoryStream.Read(compressedData, 0, compressedData.Length);
var gZipBuffer = new byte[compressedData.Length + 4]; var gZipBuffer = new byte[compressedData.Length + 4];
Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length); Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length); // bytes 4.. are the gzip content
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4); // bytes 0..3 are the length of the uncompressed string
return Convert.ToBase64String(gZipBuffer); return Convert.ToBase64String(gZipBuffer);
} }
private string DecompressString(string compressedText) private string DecompressString(string compressedText)
{ {
byte[] gZipBuffer = Convert.FromBase64String(compressedText); byte[] gZipBuffer = Convert.FromBase64String(compressedText);
using (var memoryStream = new MemoryStream())
{ using var memoryStream = new MemoryStream();
int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
int dataLength = BitConverter.ToInt32(gZipBuffer[..4], 0);
memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4); memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);
var buffer = new byte[dataLength];
memoryStream.Position = 0; memoryStream.Position = 0;
byte[] buffer = null;
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
gZipStream.Read(buffer, 0, buffer.Length); {
return Encoding.UTF8.GetString(buffer); buffer = gZipStream.ReadAllToByteArray();
if (dataLength != buffer.Length) throw new Exception("not enough data in gzip");
} }
return Encoding.UTF8.GetString(buffer);
} }
public static implicit operator GZippedString(string v) => new GZippedString{Value = v}; public static implicit operator GZippedString(string v) => new GZippedString{Value = v};