| File: Utils\StreamExtensions.cs | Web Access |
| Project: src\src\Microsoft.ML.FastTree\Microsoft.ML.FastTree.csproj (Microsoft.ML.FastTree) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.IO; using System.IO.Compression; using Microsoft.ML.Internal.Utilities; namespace Microsoft.ML.Trainers.FastTree { internal static class StreamExtensions { /// <summary> /// A stream class that suppresses the dispose signal /// </summary> private sealed class UndisposableStream : Stream { private readonly Stream _inner; public override bool CanRead => _inner.CanRead; public override bool CanSeek => _inner.CanSeek; public override bool CanWrite => _inner.CanWrite; public override long Position { get { return _inner.Position; } set { _inner.Position = value; } } public UndisposableStream(Stream inner) { _inner = inner; } public override void Flush() { _inner.Flush(); } public override long Length => _inner.Length; public override int Read(byte[] buffer, int offset, int count) { return _inner.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return _inner.Seek(offset, origin); } public override void SetLength(long value) { _inner.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { _inner.Write(buffer, offset, count); } } /// <summary> /// Reads a compressed array of byte from the stream (written by WriteCompressed) /// </summary> /// <param name="stream">The stream to read from</param> /// <returns>The decompressed bytes</returns> public static byte[] ReadCompressed(this Stream stream) { BinaryReader reader = new BinaryReader(stream); int len = reader.ReadInt32(); byte[] array = new byte[len]; using (var ds = new DeflateStream(stream, CompressionMode.Decompress)) ds.ReadExactly(array, 0, len); return array; } /// <summary> /// Writes an array of bytes to the stream with compression /// </summary> /// <param name="stream">Stream to write to</param> /// <param name="array">Array to write</param> /// <param name="offset">The byte offset into the array to write</param> /// <param name="count">The number of bytes from the array to write</param> public static void WriteCompressed(this Stream stream, byte[] array, int offset, int count) { // we don't want the DeflateStream to close the input stream // but we have to dispose the DeflateStream in order for it to flush (according to the documentation) // so wrap the input stream in an UndisposableStream stream = new UndisposableStream(stream); using (BinaryWriter writer = new BinaryWriter(stream)) writer.Write(count); using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Compress)) ds.Write(array, offset, count); } /// <summary> /// Writes an array of bytes to the stream with compression /// </summary> /// <param name="stream">Stream to write to</param> /// <param name="array">Array to write</param> public static void WriteCompressed(this Stream stream, byte[] array) { stream.WriteCompressed(array, 0, array.Length); } } }