BrotliDecompressor.cs 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System;
  2. using Best.HTTP.Shared.Streams;
  3. using Best.HTTP.Shared.Logger;
  4. using Best.HTTP.Shared.PlatformSupport.Memory;
  5. namespace Best.HTTP.Response.Decompression
  6. {
  7. public sealed class BrotliDecompressor : IDecompressor
  8. {
  9. #if ((NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (UNITY_EDITOR || (!UNITY_WEBGL && !(ENABLE_MONO && UNITY_ANDROID)))) && !BESTHTTP_DISABLE_BROTLI
  10. private BufferSegmentStream decompressorInputStream;
  11. private BufferPoolMemoryStream decompressorOutputStream;
  12. private System.IO.Compression.BrotliStream decompressorStream;
  13. byte[] copyBuffer = null;
  14. #endif
  15. private int _minLengthToDecompress;
  16. public static bool IsSupported()
  17. {
  18. // Not enabled under android with the mono runtime
  19. #if ((NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (UNITY_EDITOR || (!UNITY_WEBGL && !(ENABLE_MONO && UNITY_ANDROID)))) && !BESTHTTP_DISABLE_BROTLI
  20. return true;
  21. #else
  22. return false;
  23. #endif
  24. }
  25. public BrotliDecompressor(int minLengthToDecompress)
  26. {
  27. this._minLengthToDecompress = minLengthToDecompress;
  28. }
  29. public (BufferSegment decompressed, bool releaseTheOld) Decompress(BufferSegment segment, bool forceDecompress, bool dataCanBeLarger, LoggingContext context)
  30. {
  31. #if ((NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (UNITY_EDITOR || (!UNITY_WEBGL && !(ENABLE_MONO && UNITY_ANDROID)))) && !BESTHTTP_DISABLE_BROTLI
  32. if (decompressorInputStream == null)
  33. decompressorInputStream = new BufferSegmentStream();
  34. if (segment.Data != null)
  35. decompressorInputStream.Write(segment);
  36. if (!forceDecompress && decompressorInputStream.Length < _minLengthToDecompress)
  37. return (BufferSegment.Empty, false);
  38. if (decompressorStream == null)
  39. {
  40. decompressorStream = new System.IO.Compression.BrotliStream(decompressorInputStream,
  41. System.IO.Compression.CompressionMode.Decompress,
  42. true);
  43. }
  44. if (decompressorOutputStream == null)
  45. decompressorOutputStream = new BufferPoolMemoryStream();
  46. decompressorOutputStream.SetLength(0);
  47. if (copyBuffer == null)
  48. copyBuffer = BufferPool.Get(4 * 1024, true);
  49. int readCount;
  50. int sumReadCount = 0;
  51. while ((readCount = decompressorStream.Read(copyBuffer, 0, copyBuffer.Length)) != 0)
  52. {
  53. decompressorOutputStream.Write(copyBuffer, 0, readCount);
  54. sumReadCount += readCount;
  55. }
  56. byte[] result = decompressorOutputStream.ToArray(dataCanBeLarger, context);
  57. return (new BufferSegment(result, 0, dataCanBeLarger ? (int)decompressorOutputStream.Length : result.Length), false);
  58. #else
  59. return (BufferSegment.Empty, false);
  60. #endif
  61. }
  62. public void Dispose()
  63. {
  64. #if ((NET_STANDARD_2_1 || UNITY_2021_2_OR_NEWER) && (UNITY_EDITOR || (!UNITY_WEBGL && !(ENABLE_MONO && UNITY_ANDROID)))) && !BESTHTTP_DISABLE_BROTLI
  65. if (decompressorStream != null)
  66. decompressorStream.Dispose();
  67. decompressorStream = null;
  68. if (decompressorInputStream != null)
  69. decompressorInputStream.Dispose();
  70. decompressorInputStream = null;
  71. if (decompressorOutputStream != null)
  72. decompressorOutputStream.Dispose();
  73. decompressorOutputStream = null;
  74. BufferPool.Release(copyBuffer);
  75. copyBuffer = null;
  76. #endif
  77. }
  78. }
  79. }