public override void Write(byte[] buffer, int offset, int count)
        {
            // Keep buffering until we have 16 bytes of IV.
            if (this.bufferIV && this.position < 16)
            {
                int bytesToCopy = 16 - (int)this.position;
                bytesToCopy = count > bytesToCopy ? bytesToCopy : count;
                Array.Copy(buffer, offset, this.iv, (int)this.position, bytesToCopy);
                this.position += bytesToCopy;
                offset        += bytesToCopy;
                count         -= bytesToCopy;
            }

            // Wrap user stream with LengthLimitingStream. This stream will be used to discard the extra bytes we downloaded in order to deal with AES block size.
            // Create crypto stream around the length limiting stream once per download and start writing to it. During retries, the state is maintained and
            // new crypto streams will not be created each time.
            if (this.cryptoStream == null)
            {
                LengthLimitingStream lengthLimitingStream = new LengthLimitingStream(this.userStream, this.discardFirst, this.userProvidedLength);
                this.cryptoStream = this.encryptionPolicy.DecryptBlob(lengthLimitingStream, this.metadata, out this.transform, this.requireEncryption, iv: !this.bufferIV ? null : this.iv, noPadding: this.noPadding);
            }

            // Route the remaining data through the crypto stream.
            if (count > 0)
            {
                this.cryptoStream.Write(buffer, offset, count);
                this.position += count;
            }
        }
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            StorageAsyncResult <NullType> storageAsyncResult = new StorageAsyncResult <NullType>(callback, state);

            // Keep buffering until we have 16 bytes of IV.
            if (this.bufferIV && this.position < 16)
            {
                int bytesToCopy = 16 - (int)this.position;
                bytesToCopy = count > bytesToCopy ? bytesToCopy : count;
                Array.Copy(buffer, offset, this.iv, (int)this.position, bytesToCopy);
                this.position += bytesToCopy;
                offset        += bytesToCopy;
                count         -= bytesToCopy;

                if (this.position < 16)
                {
                    storageAsyncResult.OnComplete();
                    return(storageAsyncResult);
                }
            }

            // Wrap user stream with LengthLimitingStream. This stream will be used to discard the extra bytes we downloaded in order to deal with AES block size.
            // Create crypto stream around the length limiting stream once per download and start writing to it. During retries, the state is maintained and
            // new crypto streams will not be created each time.
            if (this.cryptoStream == null)
            {
                LengthLimitingStream lengthLimitingStream = new LengthLimitingStream(this.userStream, this.discardFirst, this.userProvidedLength);
                this.cryptoStream = this.encryptionPolicy.DecryptBlob(lengthLimitingStream, this.metadata, out this.transform, this.requireEncryption, iv: !this.bufferIV ? null : this.iv, noPadding: this.noPadding);
            }

            if (count <= 0)
            {
                storageAsyncResult.OnComplete();
            }
            else
            {
                // Route the remaining data through the crypto stream.
                storageAsyncResult.OperationState = count;
                this.cryptoStream.BeginWrite(buffer, offset, count, this.WriteStreamCallback, storageAsyncResult);
            }

            return(storageAsyncResult);
        }
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            // Keep buffering until we have 16 bytes of IV.
            if (this.bufferIV && this.position < 16)
            {
                int bytesToCopy = 16 - (int)this.position;
                bytesToCopy = count > bytesToCopy ? bytesToCopy : count;
                Array.Copy(buffer, offset, this.iv, (int)this.position, bytesToCopy);
                this.position += bytesToCopy;
                offset += bytesToCopy;
                count -= bytesToCopy;
            }

            // Wrap user stream with LengthLimitingStream. This stream will be used to discard the extra bytes we downloaded in order to deal with AES block size.
            // Create crypto stream around the length limiting stream once per download and start writing to it. During retries, the state is maintained and 
            // new crypto streams will not be created each time. 
            if (this.cryptoStream == null)
            {
                LengthLimitingStream lengthLimitingStream = new LengthLimitingStream(this.userStream, this.discardFirst, this.userProvidedLength);
                this.cryptoStream = this.encryptionPolicy.DecryptBlob(lengthLimitingStream, this.metadata, out this.transform, this.requireEncryption, iv: !this.bufferIV ? null : this.iv, noPadding: this.noPadding);
            }

            StorageAsyncResult<NullType> storageAsyncResult = new StorageAsyncResult<NullType>(callback, state);
            if (count <= 0)
            {
                storageAsyncResult.OnComplete();
            }
            else
            {
                // Route the remaining data through the crypto stream.
                storageAsyncResult.OperationState = count;
                this.cryptoStream.BeginWrite(buffer, offset, count, this.WriteStreamCallback, storageAsyncResult);
            }

            return storageAsyncResult;
        }
        public override void Write(byte[] buffer, int offset, int count)
        {
            // Keep buffering until we have 16 bytes of IV.
            if (this.bufferIV && this.position < 16)
            {
                int bytesToCopy = 16 - (int)this.position;
                bytesToCopy = count > bytesToCopy ? bytesToCopy : count;
                Array.Copy(buffer, offset, this.iv, (int)this.position, bytesToCopy);
                this.position += bytesToCopy;
                offset += bytesToCopy;
                count -= bytesToCopy;
            }

            // Wrap user stream with LengthLimitingStream. This stream will be used to discard the extra bytes we downloaded in order to deal with AES block size.
            // Create crypto stream around the length limiting stream once per download and start writing to it. During retries, the state is maintained and 
            // new crypto streams will not be created each time. 
            if (this.cryptoStream == null)
            {
                LengthLimitingStream lengthLimitingStream = new LengthLimitingStream(this.userStream, this.discardFirst, this.userProvidedLength);
                this.cryptoStream = this.encryptionPolicy.DecryptBlob(lengthLimitingStream, this.metadata, out this.transform, this.requireEncryption, iv: !this.bufferIV ? null : this.iv, noPadding: this.noPadding);
            }

            // Route the remaining data through the crypto stream.
            if (count > 0)
            {
                this.cryptoStream.Write(buffer, offset, count);
                this.position += count;
            }
        }