GQ_Communicate/GQ_VR/Assets/Best HTTP/Source/Decompression/BrotliDecompressor.cs

91 lines
3.3 KiB
C#

using System;
using BestHTTP.Extensions;
using BestHTTP.PlatformSupport.Memory;
namespace BestHTTP.Decompression
{
public sealed class BrotliDecompressor : IDecompressor
{
#if (NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (!(ENABLE_MONO && UNITY_ANDROID) || (!UNITY_WEBGL || UNITY_EDITOR))
private BufferPoolMemoryStream decompressorInputStream;
private BufferPoolMemoryStream decompressorOutputStream;
private System.IO.Compression.BrotliStream decompressorStream;
#endif
private int MinLengthToDecompress = 256;
public static bool IsSupported()
{
// Not enabled under android with the mono runtime
#if (NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (!(ENABLE_MONO && UNITY_ANDROID) || (!UNITY_WEBGL || UNITY_EDITOR))
return true;
#else
return false;
#endif
}
public BrotliDecompressor(int minLengthToDecompress)
{
this.MinLengthToDecompress = minLengthToDecompress;
}
public DecompressedData Decompress(byte[] data, int offset, int count, bool forceDecompress = false, bool dataCanBeLarger = false)
{
#if (NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (!(ENABLE_MONO && UNITY_ANDROID) || (!UNITY_WEBGL || UNITY_EDITOR))
if (decompressorInputStream == null)
decompressorInputStream = new BufferPoolMemoryStream(count);
if (data != null)
decompressorInputStream.Write(data, offset, count);
if (!forceDecompress && decompressorInputStream.Length < MinLengthToDecompress)
return new DecompressedData(null, 0);
decompressorInputStream.Position = 0;
if (decompressorStream == null)
{
decompressorStream = new System.IO.Compression.BrotliStream(decompressorInputStream,
System.IO.Compression.CompressionMode.Decompress,
true);
}
if (decompressorOutputStream == null)
decompressorOutputStream = new BufferPoolMemoryStream();
decompressorOutputStream.SetLength(0);
byte[] copyBuffer = BufferPool.Get(1024, true);
int readCount;
int sumReadCount = 0;
while ((readCount = decompressorStream.Read(copyBuffer, 0, copyBuffer.Length)) != 0)
{
decompressorOutputStream.Write(copyBuffer, 0, readCount);
sumReadCount += readCount;
}
BufferPool.Release(copyBuffer);
// If no read is done (returned with any data) don't zero out the input stream, as it would delete any not yet used data.
if (sumReadCount > 0)
decompressorStream.SetLength(0);
byte[] result = decompressorOutputStream.ToArray(dataCanBeLarger);
return new DecompressedData(result, dataCanBeLarger ? (int)decompressorOutputStream.Length : result.Length);
#else
return default(DecompressedData);
#endif
}
public void Dispose()
{
#if (NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (!(ENABLE_MONO && UNITY_ANDROID) || (!UNITY_WEBGL || UNITY_EDITOR))
this.decompressorStream?.Dispose();
this.decompressorStream = null;
#endif
}
}
}