/// <summary> /// Decompress a stream onto given output stream. /// </summary> /// <param name="source">A source <see cref="Stream"/> to decompress.</param> /// <param name="destination">The destination <see cref="Stream"/> to decompress to.</param> /// <param name="progressHandler">A <see cref="Action"/> handler to monitor the action's progress.</param> public static void Decompress(this Stream source, Stream destination, Action <ProcessProgress <long> > progressHandler) { ProcessProgressHandler <long> progress = null; byte[] inBuffer; byte[] outBuffer; byte[] lengthBuffer = BitConverter.GetBytes((int)0); int read, size; long total = 0, length = -1; // Send initial progress event if ((object)progressHandler != null) { try { if (source.CanSeek) { length = source.Length; } } catch { length = -1; } // Create a new progress handler to track compression progress progress = new ProcessProgressHandler <long>(progressHandler, "Uncompress", length); progress.Complete = 0; } // Read compression version from stream byte[] versionBuffer = new byte[1]; if (source.Read(versionBuffer, 0, 1) > 0) { if (versionBuffer[0] != CompressionVersion) { throw new InvalidOperationException("Invalid compression version encountered in compressed stream - decompression aborted"); } // Read initial buffer read = source.Read(lengthBuffer, 0, lengthBuffer.Length); while (read > 0) { // Convert the byte array containing the buffer size into an integer size = BitConverter.ToInt32(lengthBuffer, 0); if (size > 0) { // Create and read the next buffer inBuffer = new byte[size]; read = source.Read(inBuffer, 0, size); if (read > 0) { // Uncompress buffer outBuffer = inBuffer.Decompress(); destination.Write(outBuffer, 0, outBuffer.Length); } // Update decompression progress if ((object)progressHandler != null) { total += (read + lengthBuffer.Length); progress.Complete = total; } } // Read the size of the next buffer from the stream read = source.Read(lengthBuffer, 0, lengthBuffer.Length); } } }
/// <summary> /// Compress a stream onto given output stream using specified compression strength. /// </summary> /// <param name="source">The <see cref="Stream"/> to compress.</param> /// <param name="strength">The <see cref="CompressionStrength"/> of the compression.</param> /// <param name="destination">The <see cref="Stream"/> destination.</param> /// <param name="progressHandler">The progress handler to check progress.</param> public static void Compress(this Stream source, Stream destination, CompressionStrength strength, Action <ProcessProgress <long> > progressHandler) { ProcessProgressHandler <long> progress = null; byte[] inBuffer = new byte[BufferSize]; byte[] outBuffer; byte[] lengthBuffer; int read; long total = 0, length = -1; // Send initial progress event if ((object)progressHandler != null) { try { if (source.CanSeek) { length = source.Length; } } catch { length = -1; } // Create a new progress handler to track compression progress progress = new ProcessProgressHandler <long>(progressHandler, "Compress", length); progress.Complete = 0; } // Read initial buffer read = source.Read(inBuffer, 0, BufferSize); // Write compression version into stream byte[] version = new byte[1]; version[0] = CompressionVersion; destination.Write(version, 0, 1); while (read > 0) { // Compress buffer - note that we are only going to compress used part of buffer, // we don't want any left over garbage to end up in compressed stream... outBuffer = inBuffer.Compress(0, read, strength); // The output stream is hopefully smaller than the input stream, so we prepend the final size of // each compressed buffer into the destination output stream so that we can safely uncompress // the stream in a "chunked" fashion later... lengthBuffer = BitConverter.GetBytes(outBuffer.Length); destination.Write(lengthBuffer, 0, lengthBuffer.Length); destination.Write(outBuffer, 0, outBuffer.Length); // Update compression progress if ((object)progressHandler != null) { total += read; progress.Complete = total; } // Read next buffer read = source.Read(inBuffer, 0, BufferSize); } }
/// <summary> /// Encrypts input stream onto output stream for the given parameters. /// </summary> /// <param name="source">Source stream that contains data to encrypt.</param> /// <param name="destination">Destination stream used to hold encrypted data.</param> /// <param name="key">Encryption key to use to encrypt stream.</param> /// <param name="iv">Initialization vector to use to encrypt stream.</param> /// <param name="strength">Cryptographic strength to use when encrypting stream.</param> /// <param name="progressHandler">Optional delegate to handle progress updates for encrypting large streams.</param> public static void Encrypt(this Stream source, Stream destination, byte[] key, byte[] iv, CipherStrength strength, Action<ProcessProgress<long>> progressHandler) { ProcessProgressHandler<long> progress = null; byte[] inBuffer = new byte[Standard.BufferSize]; byte[] outBuffer, lengthBuffer; long total = 0; long length = -1; int read; // Sends initial progress event. if ((object)progressHandler != null) { try { if (source.CanSeek) length = source.Length; } catch { length = -1; } // Create a new progress handler to track encryption progress progress = new ProcessProgressHandler<long>(progressHandler, "Encrypt", length); progress.Complete = 0; } // Reads initial buffer. read = source.Read(inBuffer, 0, Standard.BufferSize); while (read > 0) { // Encrypts buffer. outBuffer = inBuffer.BlockCopy(0, read).Encrypt(key, iv, strength); // The destination encryption stream length does not have to be same as the input stream length, so we // prepend the final size of each encrypted buffer onto the destination output stream so that we can // safely decrypt the stream in a "chunked" fashion later. lengthBuffer = BitConverter.GetBytes(outBuffer.Length); destination.Write(lengthBuffer, 0, lengthBuffer.Length); destination.Write(outBuffer, 0, outBuffer.Length); // Updates encryption progress. if ((object)progressHandler != null) { total += read; progress.Complete = total; } // Reads next buffer. read = source.Read(inBuffer, 0, Standard.BufferSize); } }
/// <summary> /// Decrypts input stream onto output stream for the given parameters. /// </summary> /// <param name="source">Source stream that contains data to decrypt.</param> /// <param name="destination">Destination stream used to hold decrypted data.</param> /// <param name="key">Encryption key to use to decrypt stream.</param> /// <param name="iv">Initialization vector to use to decrypt stream.</param> /// <param name="strength">Cryptographic strength to use when decrypting stream.</param> /// <param name="progressHandler">Optional delegate to handle progress updates for decrypting large streams.</param> public static void Decrypt(this Stream source, Stream destination, byte[] key, byte[] iv, CipherStrength strength, Action<ProcessProgress<long>> progressHandler) { ProcessProgressHandler<long> progress = null; byte[] inBuffer, outBuffer; byte[] lengthBuffer = BitConverter.GetBytes((int)0); long total = 0; long length = -1; int size, read; // Sends initial progress event. if ((object)progressHandler != null) { try { if (source.CanSeek) length = source.Length; } catch { length = -1; } // Create a new progress handler to track decryption progress progress = new ProcessProgressHandler<long>(progressHandler, "Decrypt", length); progress.Complete = 0; } // When the source stream was encrypted, it was known that the encrypted stream length did not have to be same as // the input stream length. We prepended the final size of the each encrypted buffer onto the destination // output stream (now the input stream to this function), so that we could safely decrypt the stream in a // "chunked" fashion, hence the following: // Reads the size of the next buffer from the stream. read = source.Read(lengthBuffer, 0, lengthBuffer.Length); while (read > 0) { // Converts the byte array containing the buffer size into an integer. size = BitConverter.ToInt32(lengthBuffer, 0); if (size > 0) { // Creates and reads the next buffer. inBuffer = new byte[size]; read = source.Read(inBuffer, 0, size); if (read > 0) { // Decrypts buffer. outBuffer = inBuffer.Decrypt(key, iv, strength); destination.Write(outBuffer, 0, outBuffer.Length); // Updates decryption progress. if ((object)progressHandler != null) { total += (read + lengthBuffer.Length); progress.Complete = total; } } } // Reads the size of the next buffer from the stream. read = source.Read(lengthBuffer, 0, lengthBuffer.Length); } }
/// <summary>Uncompress a stream onto given output stream.</summary> /// <param name="source">A source <see cref="Stream"/> to decompress.</param> /// <param name="destination">The destination <see cref="Stream"/> to decompress to.</param> /// <param name="progressHandler">A <see cref="Action"/> handler to monitor the action's progress.</param> public static void Decompress(this Stream source, Stream destination, Action<ProcessProgress<long>> progressHandler) { ProcessProgressHandler<long> progress = null; byte[] inBuffer; byte[] outBuffer; byte[] lengthBuffer = BitConverter.GetBytes((int)0); int read, size; long total = 0, length = -1; // Send initial progress event if (progressHandler != null) { try { if (source.CanSeek) length = source.Length; } catch { length = -1; } // Create a new progress handler to track compression progress progress = new ProcessProgressHandler<long>(progressHandler, "Uncompress", length); progress.Complete = 0; } // Read compression version from stream byte[] versionBuffer = new byte[1]; if (source.Read(versionBuffer, 0, 1) > 0) { if (versionBuffer[0] != CompressionVersion) throw new InvalidOperationException("Invalid compression version encountered in compressed stream - decompression aborted."); // Read initial buffer read = source.Read(lengthBuffer, 0, lengthBuffer.Length); while (read > 0) { // Convert the byte array containing the buffer size into an integer size = BitConverter.ToInt32(lengthBuffer, 0); if (size > 0) { // Create and read the next buffer inBuffer = new byte[size]; read = source.Read(inBuffer, 0, size); if (read > 0) { // Uncompress buffer outBuffer = inBuffer.Decompress(BufferSize); destination.Write(outBuffer, 0, outBuffer.Length); } // Update decompression progress if (progressHandler != null) { total += (read + lengthBuffer.Length); progress.Complete = total; } } // Read the size of the next buffer from the stream read = source.Read(lengthBuffer, 0, lengthBuffer.Length); } } }
/// <summary>Compress a stream onto given output stream using specified compression strength.</summary> /// <param name="source">The <see cref="Stream"/> to compress.</param> /// <param name="strength">The <see cref="CompressionStrength"/> of the compression.</param> /// <param name="destination">The <see cref="Stream"/> destination.</param> /// <param name="progressHandler">The progress handler to check progress.</param> public static void Compress(this Stream source, Stream destination, CompressionStrength strength, Action<ProcessProgress<long>> progressHandler) { ProcessProgressHandler<long> progress = null; byte[] inBuffer = new byte[BufferSize]; byte[] outBuffer; byte[] lengthBuffer; int read; long total = 0, length = -1; // Send initial progress event if (progressHandler != null) { try { if (source.CanSeek) length = source.Length; } catch { length = -1; } // Create a new progress handler to track compression progress progress = new ProcessProgressHandler<long>(progressHandler, "Compress", length); progress.Complete = 0; } // Read initial buffer read = source.Read(inBuffer, 0, BufferSize); // Write compression version into stream byte[] version = new byte[1]; version[0] = CompressionVersion; destination.Write(version, 0, 1); while (read > 0) { // Compress buffer - note that we are only going to compress used part of buffer, // we don't want any left over garbage to end up in compressed stream... outBuffer = inBuffer.Compress(0, read, strength); // The output stream is hopefully smaller than the input stream, so we prepend the final size of // each compressed buffer into the destination output stream so that we can safely uncompress // the stream in a "chunked" fashion later... lengthBuffer = BitConverter.GetBytes(outBuffer.Length); destination.Write(lengthBuffer, 0, lengthBuffer.Length); destination.Write(outBuffer, 0, outBuffer.Length); // Update compression progress if (progressHandler != null) { total += read; progress.Complete = total; } // Read next buffer read = source.Read(inBuffer, 0, BufferSize); } }