예제 #1
0
        /// <inheritdoc/>
        public async Task <UInt32> TransformChunkAsync(
            Stream input,
            UInt32 inputChunkSize,
            Stream output,
            NefsDataTransform transform,
            NefsProgress p)
        {
            using (var transformedStream = new MemoryStream())
            {
                // Copy raw chunk to temp stream
                await input.CopyPartialAsync(transformedStream, inputChunkSize, p.CancellationToken);

                transformedStream.Seek(0, SeekOrigin.Begin);

                // Compress
                if (transform.IsZlibCompressed)
                {
                    using (var tempStream = new MemoryStream())
                    {
                        await DeflateHelper.DeflateAsync(transformedStream, (int)inputChunkSize, tempStream);

                        tempStream.Seek(0, SeekOrigin.Begin);

                        transformedStream.Seek(0, SeekOrigin.Begin);
                        await tempStream.CopyPartialAsync(transformedStream, tempStream.Length, p.CancellationToken);

                        transformedStream.Seek(0, SeekOrigin.Begin);
                        transformedStream.SetLength(tempStream.Length);
                    }
                }

                // Encrypt
                if (transform.IsAesEncrypted)
                {
                    using (var aesManager = this.CreateAesManager(transform.Aes256Key))
                        using (var cryptoStream = new CryptoStream(transformedStream, aesManager.CreateEncryptor(), CryptoStreamMode.Read, leaveOpen: true))
                            using (var tempStream = new MemoryStream())
                            {
                                await cryptoStream.CopyToAsync(tempStream, p.CancellationToken);

                                tempStream.Seek(0, SeekOrigin.Begin);

                                transformedStream.Seek(0, SeekOrigin.Begin);
                                await tempStream.CopyPartialAsync(transformedStream, tempStream.Length, p.CancellationToken);

                                transformedStream.Seek(0, SeekOrigin.Begin);
                                transformedStream.SetLength(tempStream.Length);
                            }
                }

                // Copy transformed chunk to output stream
                await transformedStream.CopyToAsync(output, p.CancellationToken);

                // Return size of transformed chunk
                return((uint)transformedStream.Length);
            }
        }
예제 #2
0
        /// <inheritdoc/>
        public async Task <NefsItemSize> CompressAsync(
            Stream input,
            Int64 inputOffset,
            UInt32 inputLength,
            Stream output,
            Int64 outputOffset,
            UInt32 chunkSize,
            NefsProgress p)
        {
            var chunkSizes = new List <UInt32>();

            input.Seek(inputOffset, SeekOrigin.Begin);
            output.Seek(outputOffset, SeekOrigin.Begin);

            // Split file into chunks and compress them
            using (var t = p.BeginTask(1.0f, $"Compressing stream"))
            {
                var lastChunkSize  = 0;
                var totalChunkSize = 0;
                var lastBytesRead  = 0;
                var bytesRemaining = (int)inputLength;

                // Determine how many chunks to split file into
                var numChunks = (int)Math.Ceiling(inputLength / (double)chunkSize);

                for (var i = 0; i < numChunks; ++i)
                {
                    using (var st = p.BeginSubTask(1.0f / numChunks, $"Compressing chunk {i + 1}/{numChunks}"))
                    {
                        var nextBytes = Math.Min(chunkSize, bytesRemaining);

                        // Compress this chunk and write it to the output file
                        (lastBytesRead, lastChunkSize) = await DeflateHelper.DeflateAsync(input, (int)nextBytes, output, p.CancellationToken);

                        totalChunkSize += lastChunkSize;
                        bytesRemaining -= lastBytesRead;

                        // Record the total compressed size after this chunk
                        chunkSizes.Add((UInt32)totalChunkSize);
                    }
                }
            }

            // Return item size
            return(new NefsItemSize(inputLength, chunkSizes));
        }