Exemple #1
0
        /// <summary>
        /// Initializes a new instance of the FileWriteStreamBase class for a file.
        /// </summary>
        /// <param name="file">File reference to write to.</param>
        /// <param name="fileSize">Size of the file.</param>
        /// <param name="createNew">Use <c>true</c> if the file is newly created, <c>false</c> otherwise.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the file. If <c>null</c>, no condition is used.</param>
        /// <param name="options">An <see cref="FileRequestOptions"/> object that specifies additional options for the request.</param>
        /// <param name="operationContext">An <see cref="OperationContext"/> object for tracking the current operation.</param>
        protected FileWriteStreamBase(CloudFile file, long fileSize, bool createNew, AccessCondition accessCondition, FileRequestOptions options, OperationContext operationContext)
            : base()
        {
            this.internalBuffer       = new MultiBufferMemoryStream(file.ServiceClient.BufferManager);
            this.currentOffset        = 0;
            this.accessCondition      = accessCondition;
            this.options              = options;
            this.operationContext     = operationContext;
            this.noPendingWritesEvent = new CounterEventAsync();
            this.fileChecksum         = new ChecksumWrapper(this.options.ChecksumOptions.StoreContentMD5.Value, this.options.ChecksumOptions.StoreContentCRC64.Value);
            this.rangeChecksum        = new ChecksumWrapper(this.options.ChecksumOptions.UseTransactionalMD5.Value, this.options.ChecksumOptions.UseTransactionalCRC64.Value);
#if !(NETCORE || WINDOWS_RT)
            this.parallelOperationSemaphoreAsync = new AsyncSemaphoreAsync(options.ParallelOperationThreadCount.Value);
#else
            this.parallelOperationSemaphore = new AsyncSemaphore(options.ParallelOperationThreadCount.Value);
#endif
            this.lastException     = null;
            this.committed         = false;
            this.disposed          = false;
            this.currentFileOffset = 0;
            this.file     = file;
            this.fileSize = fileSize;
            this.streamWriteSizeInBytes = file.StreamWriteSizeInBytes;
            this.newFile = createNew;
        }
Exemple #2
0
        /// <summary>
        /// Releases the file resources used by the Stream.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.fileChecksum != null)
                {
                    this.fileChecksum.Dispose();
                    this.fileChecksum = null;
                }

                if (this.rangeChecksum != null)
                {
                    this.rangeChecksum.Dispose();
                    this.rangeChecksum = null;
                }

                if (this.internalBuffer != null)
                {
                    this.internalBuffer.Dispose();
                    this.internalBuffer = null;
                }
            }

            base.Dispose(disposing);
        }
Exemple #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FileReadStreamBase"/> class.
        /// </summary>
        /// <param name="file">File reference to read from</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the file. If <c>null</c>, no condition is used.</param>
        /// <param name="options">An <see cref="FileRequestOptions"/> object that specifies additional options for the request.</param>
        /// <param name="operationContext">An <see cref="OperationContext"/> object for tracking the current operation.</param>
        protected FileReadStreamBase(CloudFile file, AccessCondition accessCondition, FileRequestOptions options, OperationContext operationContext)
        {
            if (options.ChecksumOptions.UseTransactionalMD5.Value)
            {
                CommonUtility.AssertInBounds("StreamMinimumReadSizeInBytes", file.StreamMinimumReadSizeInBytes, 1, Constants.MaxRangeGetContentMD5Size);
            }
            if (options.ChecksumOptions.UseTransactionalCRC64.Value)
            {
                CommonUtility.AssertInBounds("StreamMinimumReadSizeInBytes", file.StreamMinimumReadSizeInBytes, 1, Constants.MaxRangeGetContentCRC64Size);
            }

            this.file           = file;
            this.fileProperties = new FileProperties(file.Properties);
            this.currentOffset  = 0;
            this.streamMinimumReadSizeInBytes = this.file.StreamMinimumReadSizeInBytes;
            this.internalBuffer   = new MultiBufferMemoryStream(file.ServiceClient.BufferManager);
            this.accessCondition  = accessCondition;
            this.options          = options;
            this.operationContext = operationContext;
            this.fileChecksum     =
                new ChecksumWrapper(
                    calcMd5: !(this.options.ChecksumOptions.DisableContentMD5Validation.Value || string.IsNullOrEmpty(this.fileProperties.ContentChecksum.MD5)),
                    calcCrc64: !(this.options.ChecksumOptions.DisableContentCRC64Validation.Value || string.IsNullOrEmpty(this.fileProperties.ContentChecksum.CRC64))
                    );
            this.lastException = null;
        }
Exemple #4
0
        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A byte offset relative to the origin parameter.</param>
        /// <param name="origin">A value of type <c>SeekOrigin</c> indicating the reference
        /// point used to obtain the new position.</param>
        /// <returns>The new position within the current stream.</returns>
        /// <remarks>Seeking in a FileReadStream disables checksum validation.</remarks>
        public override long Seek(long offset, SeekOrigin origin)
        {
            if (this.lastException != null)
            {
                throw this.lastException;
            }

            long newOffset;

            switch (origin)
            {
            case SeekOrigin.Begin:
                newOffset = offset;
                break;

            case SeekOrigin.Current:
                newOffset = this.currentOffset + offset;
                break;

            case SeekOrigin.End:
                newOffset = this.Length + offset;
                break;

            default:
                CommonUtility.ArgumentOutOfRange("origin", origin);
                throw new ArgumentOutOfRangeException("origin");
            }

            CommonUtility.AssertInBounds("offset", newOffset, 0, this.Length);

            if (newOffset != this.currentOffset)
            {
                long bufferOffset = this.internalBuffer.Position + (newOffset - this.currentOffset);
                if ((bufferOffset >= 0) && (bufferOffset < this.internalBuffer.Length))
                {
                    this.internalBuffer.Position = bufferOffset;
                }
                else
                {
                    this.internalBuffer.SetLength(0);
                }

                this.fileChecksum  = null;
                this.currentOffset = newOffset;
            }

            return(this.currentOffset);
        }
        /// <summary>
        /// Updates the blob checksum with newly downloaded content.
        /// </summary>
        /// <param name="buffer">The buffer to read the data from.</param>
        /// <param name="offset">The byte offset in buffer at which to begin reading data.</param>
        /// <param name="count">The maximum number of bytes to read.</param>
        protected void VerifyBlobChecksum(byte[] buffer, int offset, int count)
        {
            if ((this.blobChecksum != null) && (this.lastException == null) && (count > 0))
            {
                this.blobChecksum.UpdateHash(buffer, offset, count);

                bool disposeBlobChecksum = false;

                if ((this.currentOffset == this.Length) &&
                    !string.IsNullOrEmpty(this.blobProperties.ContentChecksum.MD5) &&
                    this.blobChecksum.MD5 != default(MD5Wrapper))
                {
                    string computedMD5 = this.blobChecksum.MD5.ComputeHash();

                    if (!computedMD5.Equals(this.blobProperties.ContentChecksum.MD5))
                    {
                        this.lastException = new IOException(string.Format(
                                                                 CultureInfo.InvariantCulture,
                                                                 SR.BlobDataCorrupted,
                                                                 this.blobProperties.ContentChecksum.MD5,
                                                                 computedMD5));
                    }
                }

                if ((this.currentOffset == this.Length) &&
                    !string.IsNullOrEmpty(this.blobProperties.ContentChecksum.CRC64) &&
                    this.blobChecksum.CRC64 != default(Crc64Wrapper))
                {
                    string computedCRC64 = this.blobChecksum.CRC64.ComputeHash();

                    if (!computedCRC64.Equals(this.blobProperties.ContentChecksum.CRC64))
                    {
                        this.lastException = new IOException(string.Format(
                                                                 CultureInfo.InvariantCulture,
                                                                 SR.BlobDataCorrupted,
                                                                 this.blobProperties.ContentChecksum.CRC64,
                                                                 computedCRC64));
                    }
                }

                if (disposeBlobChecksum)
                {
                    this.blobChecksum.Dispose();
                    this.blobChecksum = null;
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the BlobWriteStreamBase class.
        /// </summary>
        /// <param name="serviceClient">The service client.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
        private BlobWriteStreamBase(CloudBlobClient serviceClient, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
            : base()
        {
            this.internalBuffer       = new MultiBufferMemoryStream(serviceClient.BufferManager);
            this.accessCondition      = accessCondition;
            this.currentOffset        = 0;
            this.options              = options;
            this.operationContext     = operationContext;
            this.noPendingWritesEvent = new CounterEventAsync();
            this.blobChecksum         = new ChecksumWrapper(this.options.ChecksumOptions.StoreContentMD5.Value, this.options.ChecksumOptions.StoreContentCRC64.Value);
            this.blockChecksum        = new ChecksumWrapper(this.options.ChecksumOptions.UseTransactionalMD5.Value, this.options.ChecksumOptions.UseTransactionalCRC64.Value);
#if WINDOWS_DESKTOP
            this.parallelOperationSemaphoreAsync = new AsyncSemaphoreAsync(options.ParallelOperationThreadCount.Value);
#else
            this.parallelOperationSemaphore = new AsyncSemaphore(options.ParallelOperationThreadCount.Value);
#endif
            this.lastException = null;
            this.committed     = false;
            this.disposed      = false;
        }