/// <summary>
 /// Internal helper method to wrap a user provided stream with the appropriate crypto stream.
 /// </summary>
 internal static Stream WrapUserStreamWithDecryptStream(CloudBlob blob, Stream userProvidedStream, BlobRequestOptions options, BlobAttributes attributes, bool rangeRead, out ICryptoTransform transform, long?endOffset = null, long?userSpecifiedLength = null, int discardFirst = 0, bool bufferIV = false)
 {
     if (!rangeRead)
     {
         // The user provided stream should be wrapped in a NonCloseableStream in order to
         // avoid closing the user stream when the crypto stream is closed to flush the final decrypted
         // block of data.
         Stream decryptStream = options.EncryptionPolicy.DecryptBlob(new NonCloseableStream(userProvidedStream), attributes.Metadata, out transform, options.RequireEncryption, null, blob.BlobType == BlobType.PageBlob);
         return(decryptStream);
     }
     else
     {
         // Check if end offset lies in the last AES block and send this information over to set the correct padding mode.
         bool noPadding = blob.BlobType == BlobType.PageBlob || (endOffset.HasValue && endOffset.Value < attributes.Properties.Length - 16);
         transform = null;
         return(new BlobDecryptStream(userProvidedStream, attributes.Metadata, userSpecifiedLength, discardFirst, bufferIV, noPadding, options.EncryptionPolicy, options.RequireEncryption));
     }
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CloudBlockBlob"/> class.
 /// </summary>
 /// <param name="attributes">The attributes.</param>
 /// <param name="serviceClient">The service client.</param>
 internal CloudBlockBlob(BlobAttributes attributes, CloudBlobClient serviceClient)
     : base(attributes, serviceClient)
 {
     this.Properties.BlobType = BlobType.BlockBlob;
 }