MessageEncoderCompressionHandler.cs 4.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // <copyright>
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // </copyright>
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System;
  7. using System.IO;
  8. using System.IO.Compression;
  9. internal static class MessageEncoderCompressionHandler
  10. {
  11. internal const string GZipContentEncoding = "gzip";
  12. internal const string DeflateContentEncoding = "deflate";
  13. private const int DecompressBlockSize = 1024;
  14. internal static void DecompressBuffer(ref ArraySegment<byte> buffer, BufferManager bufferManager, CompressionFormat compressionFormat, long maxReceivedMessageSize)
  15. {
  16. MemoryStream memoryStream = new MemoryStream(buffer.Array, buffer.Offset, buffer.Count);
  17. int maxDecompressedSize = (int)Math.Min(maxReceivedMessageSize, int.MaxValue);
  18. using (BufferManagerOutputStream bufferedOutStream = new BufferManagerOutputStream(SR.MaxReceivedMessageSizeExceeded, 1024, maxDecompressedSize, bufferManager))
  19. {
  20. bufferedOutStream.Write(buffer.Array, 0, buffer.Offset);
  21. byte[] tempBuffer = bufferManager.TakeBuffer(DecompressBlockSize);
  22. try
  23. {
  24. using (Stream ds = compressionFormat == CompressionFormat.GZip ?
  25. (Stream)new GZipStream(memoryStream, CompressionMode.Decompress) :
  26. (Stream)new DeflateStream(memoryStream, CompressionMode.Decompress))
  27. {
  28. while (true)
  29. {
  30. int bytesRead = ds.Read(tempBuffer, 0, DecompressBlockSize);
  31. if (bytesRead > 0)
  32. {
  33. bufferedOutStream.Write(tempBuffer, 0, bytesRead);
  34. }
  35. else
  36. {
  37. break;
  38. }
  39. }
  40. }
  41. }
  42. finally
  43. {
  44. bufferManager.ReturnBuffer(tempBuffer);
  45. }
  46. int length = 0;
  47. byte[] decompressedBytes = bufferedOutStream.ToArray(out length);
  48. bufferManager.ReturnBuffer(buffer.Array);
  49. buffer = new ArraySegment<byte>(decompressedBytes, buffer.Offset, length - buffer.Offset);
  50. }
  51. }
  52. internal static void CompressBuffer(ref ArraySegment<byte> buffer, BufferManager bufferManager, CompressionFormat compressionFormat)
  53. {
  54. using (BufferManagerOutputStream bufferedOutStream = new BufferManagerOutputStream(SR.MaxSentMessageSizeExceeded, 1024, int.MaxValue, bufferManager))
  55. {
  56. bufferedOutStream.Write(buffer.Array, 0, buffer.Offset);
  57. using (Stream ds = compressionFormat == CompressionFormat.GZip ?
  58. (Stream)new GZipStream(bufferedOutStream, CompressionMode.Compress, true) :
  59. (Stream)new DeflateStream(bufferedOutStream, CompressionMode.Compress, true))
  60. {
  61. ds.Write(buffer.Array, buffer.Offset, buffer.Count);
  62. }
  63. int length = 0;
  64. byte[] compressedBytes = bufferedOutStream.ToArray(out length);
  65. bufferManager.ReturnBuffer(buffer.Array);
  66. buffer = new ArraySegment<byte>(compressedBytes, buffer.Offset, length - buffer.Offset);
  67. }
  68. }
  69. internal static Stream GetDecompressStream(Stream compressedStream, CompressionFormat compressionFormat)
  70. {
  71. return compressionFormat == CompressionFormat.GZip ?
  72. (Stream)new GZipStream(compressedStream, CompressionMode.Decompress, false) :
  73. (Stream)new DeflateStream(compressedStream, CompressionMode.Decompress, false);
  74. }
  75. internal static Stream GetCompressStream(Stream uncompressedStream, CompressionFormat compressionFormat)
  76. {
  77. return compressionFormat == CompressionFormat.GZip ?
  78. (Stream)new GZipStream(uncompressedStream, CompressionMode.Compress, true) :
  79. (Stream)new DeflateStream(uncompressedStream, CompressionMode.Compress, true);
  80. }
  81. }
  82. }